source: nagslang/game_object.py@ 83:d7beca6b6762

Last change on this file since 83:d7beca6b6762 was 82:11b0017b5e4b, checked in by davidsharpe@…, 8 years ago

Fix whitespace.

File size: 4.1 KB
RevLine 
[63]1import math
[62]2
[81]3import pygame
4import pymunk
5
6from nagslang.constants import SWITCH_PUSHERS, COLLISION_TYPE_SWITCH
7
[82]8
[81]9class Puzzler(object):
10 def get_state(self, space):
11 raise NotImplementedError()
12
13 def notify(self):
14 pass
15
16
17class FloorSwitchPuzzler(Puzzler):
18 def __init__(self, shape):
19 self.shape = shape
20
21 def get_state(self, space):
22 for shape in space.shape_query(self.shape):
23 if shape.collision_type in SWITCH_PUSHERS:
24 return True
25 return False
26
[59]27
28class Physicser(object):
29 def add_to_space(self, space):
30 raise NotImplementedError()
31
32 def remove_from_space(self, space):
33 raise NotImplementedError()
34
[63]35 def render_position(self, surface):
36 raise NotImplementedError()
37
38 def render_angle(self):
[59]39 raise NotImplementedError()
40
41
42class NullPhysicser(Physicser):
43 def add_to_space(self, space):
44 pass
45
46 def remove_from_space(self, space):
47 pass
48
49 def render_position(self):
50 return (0, 0)
51
[63]52 def render_angle(self):
53 return 0
54
[59]55
56class SingleShapePhysicser(Physicser):
57 def __init__(self, shape):
58 self._shape = shape
59
60 def add_to_space(self, space):
61 space.add(self._shape, self._shape.body)
62
63 def remove_from_space(self, space):
64 space.remove(self._shape, self._shape.body)
65
66 def render_position(self, surface):
67 pos = self._shape.body.position
68 import pymunk.pygame_util
69 return pymunk.pygame_util.to_pygame(pos, surface)
[63]70
71 def render_angle(self):
72 return self._shape.body.angle
[59]73
74
75class Renderer(object):
[63]76 def render(self, surface, pos, angle):
[59]77 raise NotImplementedError()
78
79
[63]80def image_pos(image, pos):
81 return (pos[0] - image.get_width() / 2,
82 pos[1] - image.get_height() / 2)
83
84
[59]85class ImageRenderer(Renderer):
86 def __init__(self, image):
87 self._image = image
88
[63]89 def render(self, surface, pos, angle):
90 surface.blit(self._image, image_pos(self._image, pos))
91
92
93class FacingImageRenderer(Renderer):
94 def __init__(self, left_image, right_image):
95 self._images = {
96 'left': left_image,
97 'right': right_image,
98 }
99
100 def get_image(self, angle):
101 if abs(angle) < math.pi / 2:
102 return self._images['right']
103 return self._images['left']
104
105 def render(self, surface, pos, angle):
106 image = self.get_image(angle)
107 surface.blit(image, image_pos(image, pos))
[59]108
109
110class ShapeRenderer(Renderer):
111 def __init__(self, shape):
112 self._shape = shape
113
[63]114 def render(self, surface, pos, angle):
[59]115 import pymunk.pygame_util
116 pymunk.pygame_util.draw(surface, self._shape)
117
118
119class GameObject(object):
120 """A representation of a thing in the game world.
121
122 This has a rendery thing, physicsy things and maybe some other things.
123 """
124
[81]125 def __init__(self, renderer, physicser=None, puzzler=None):
[59]126 self.renderer = renderer
127 if physicser is None:
128 physicser = NullPhysicser()
129 self.physicser = physicser
[81]130 self.puzzler = puzzler
[59]131
132 def add_to_space(self, space):
133 self.physicser.add_to_space(space)
134
135 def render(self, surface):
[60]136 return self.renderer.render(
[63]137 surface, self.physicser.render_position(surface),
138 self.physicser.render_angle())
[81]139
140
141class FloorSwitch(GameObject):
142 def __init__(self, position):
143 body = pymunk.Body()
144 body.position = position
145 self.shape = pymunk.Circle(body, 30)
146 self.shape.collision_type = COLLISION_TYPE_SWITCH
147 self.shape.sensor = True
148 super(FloorSwitch, self).__init__(
149 ShapeRenderer(self.shape),
150 SingleShapePhysicser(self.shape),
151 FloorSwitchPuzzler(self.shape),
152 )
153
154 def add_to_space(self, space):
155 # XXX: Hacky hack.
156 self._space = space
157
158 def render(self, surface):
159 if self.puzzler.get_state(self._space):
160 self.shape.color = pygame.color.THECOLORS['green']
161 else:
162 self.shape.color = pygame.color.THECOLORS['red']
[82]163 super(FloorSwitch, self).render(surface)
Note: See TracBrowser for help on using the repository browser.