source: nagslang/game_object.py@ 86:a5c839994d41

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

Fix whitespace.

File size: 4.1 KB
Line 
1import math
2
3import pygame
4import pymunk
5
6from nagslang.constants import SWITCH_PUSHERS, COLLISION_TYPE_SWITCH
7
8
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
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
35 def render_position(self, surface):
36 raise NotImplementedError()
37
38 def render_angle(self):
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
52 def render_angle(self):
53 return 0
54
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)
70
71 def render_angle(self):
72 return self._shape.body.angle
73
74
75class Renderer(object):
76 def render(self, surface, pos, angle):
77 raise NotImplementedError()
78
79
80def image_pos(image, pos):
81 return (pos[0] - image.get_width() / 2,
82 pos[1] - image.get_height() / 2)
83
84
85class ImageRenderer(Renderer):
86 def __init__(self, image):
87 self._image = image
88
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))
108
109
110class ShapeRenderer(Renderer):
111 def __init__(self, shape):
112 self._shape = shape
113
114 def render(self, surface, pos, angle):
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
125 def __init__(self, renderer, physicser=None, puzzler=None):
126 self.renderer = renderer
127 if physicser is None:
128 physicser = NullPhysicser()
129 self.physicser = physicser
130 self.puzzler = puzzler
131
132 def add_to_space(self, space):
133 self.physicser.add_to_space(space)
134
135 def render(self, surface):
136 return self.renderer.render(
137 surface, self.physicser.render_position(surface),
138 self.physicser.render_angle())
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']
163 super(FloorSwitch, self).render(surface)
Note: See TracBrowser for help on using the repository browser.