source: nagslang/game_object.py@ 101:93aa745d57ff

Last change on this file since 101:93aa745d57ff was 93:d6a49f0c1e6e, checked in by Jeremy Thurgood <firxen@…>, 8 years ago

Rectangular human protagonist shape, refactored physicsers.

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