Mercurial > nagslang
comparison nagslang/protagonist.py @ 215:325c317cbfa1
Better protagonist physicser.
author | Jeremy Thurgood <firxen@gmail.com> |
---|---|
date | Wed, 04 Sep 2013 13:13:11 +0200 |
parents | 3d54fe7a2998 |
children | d98daba73055 |
comparison
equal
deleted
inserted
replaced
214:d3d602a527bd | 215:325c317cbfa1 |
---|---|
3 | 3 |
4 import math | 4 import math |
5 | 5 |
6 from nagslang import render | 6 from nagslang import render |
7 from nagslang.constants import COLLISION_TYPE_PLAYER, ZORDER_MID | 7 from nagslang.constants import COLLISION_TYPE_PLAYER, ZORDER_MID |
8 from nagslang.game_object import GameObject, SingleShapePhysicser, make_body | 8 from nagslang.game_object import GameObject, Physicser, make_body |
9 from nagslang.mutators import FLIP_H | 9 from nagslang.mutators import FLIP_H |
10 from nagslang.resources import resources | 10 from nagslang.resources import resources |
11 | |
12 | |
13 class ProtagonistPhysicser(Physicser): | |
14 def __init__(self, space, form_shapes): | |
15 self._space = space | |
16 self._form_shapes = form_shapes | |
17 | |
18 def switch_form(self, old_form, new_form): | |
19 self._space.remove(self._form_shapes[old_form]) | |
20 shape = self._form_shapes[new_form] | |
21 self._space.add(shape) | |
22 for attr, value in shape.protagonist_body_props.iteritems(): | |
23 setattr(shape.body, attr, value) | |
24 | |
25 def get_shape(self): | |
26 return self._form_shapes[self.game_object.form] | |
11 | 27 |
12 | 28 |
13 class Protagonist(GameObject): | 29 class Protagonist(GameObject): |
14 """Representation of our fearless protagonist. | 30 """Representation of our fearless protagonist. |
15 | 31 |
20 HUMAN_FORM_BACK = 'human_back' | 36 HUMAN_FORM_BACK = 'human_back' |
21 WOLF_FORM = 'wolf' | 37 WOLF_FORM = 'wolf' |
22 WOLF_FORM_BACK = 'wolf_back' | 38 WOLF_FORM_BACK = 'wolf_back' |
23 | 39 |
24 def __init__(self, space, position): | 40 def __init__(self, space, position): |
25 self._setup_physics(space, position) | 41 physicser = self._make_physics(space, position) |
26 self._setup_renderers() | 42 self._setup_renderers() |
27 self.inventory = {} | 43 self.inventory = {} |
28 self.form = self.HUMAN_FORM | 44 self.form = self.HUMAN_FORM |
29 self.render_form = self.HUMAN_FORM | 45 self.render_form = self.HUMAN_FORM |
30 | 46 |
31 super(Protagonist, self).__init__( | 47 super(Protagonist, self).__init__( |
32 self._physicsers[self.form], self._renderers[self.form]) | 48 physicser, self._renderers[self.form]) |
33 self.zorder = ZORDER_MID | 49 self.zorder = ZORDER_MID |
34 | 50 |
35 self.go_human() | 51 self.go_human() |
36 | 52 |
37 def _setup_physics(self, space, position): | 53 def _make_physics(self, space, position): |
38 self._body = make_body(10, pymunk.inf, position, 0.8) | 54 body = make_body(10, pymunk.inf, position, 0.8) |
39 | 55 body.velocity_limit = 1000 |
40 self._shapes = { | 56 |
41 self.HUMAN_FORM: pymunk.Poly( | 57 human = pymunk.Poly(body, [(-15, -30), (15, -30), (15, 30), (-15, 30)]) |
42 self._body, [(-15, -30), (15, -30), (15, 30), (-15, 30)]), | 58 human.elasticity = 1.0 |
43 self.WOLF_FORM: pymunk.Circle(self._body, 30), | 59 human.collision_type = COLLISION_TYPE_PLAYER |
60 human.protagonist_body_props = { | |
61 'mass': 10, | |
62 'damping': 0.8, | |
44 } | 63 } |
45 self._shapes[self.HUMAN_FORM].friction = 1.0 | 64 |
46 self._shapes[self.WOLF_FORM].friction = 0.05 | 65 wolf = pymunk.Circle(body, 30) |
47 self._physicsers = {} | 66 wolf.elasticity = 1.0 |
48 for form, shape in self._shapes.iteritems(): | 67 wolf.collision_type = COLLISION_TYPE_PLAYER |
49 shape.elasticity = 1.0 | 68 wolf.protagonist_body_props = { |
50 shape.collision_type = COLLISION_TYPE_PLAYER | 69 'mass': 100, |
51 self._physicsers[form] = SingleShapePhysicser(space, shape) | 70 'damping': 0.9, |
52 self.angle = 0 | 71 } |
72 | |
73 return ProtagonistPhysicser(space, { | |
74 self.HUMAN_FORM: human, | |
75 self.WOLF_FORM: wolf, | |
76 }) | |
53 | 77 |
54 def _get_image(self, name, *transforms): | 78 def _get_image(self, name, *transforms): |
55 return resources.get_image('creatures', name, transforms=transforms) | 79 return resources.get_image('creatures', name, transforms=transforms) |
56 | 80 |
57 def _setup_renderers(self): | 81 def _setup_renderers(self): |
82 self.angle = 0 | |
58 self._renderers = { | 83 self._renderers = { |
59 self.HUMAN_FORM: render.AnimatedFacingImageRenderer( | 84 self.HUMAN_FORM: render.AnimatedFacingImageRenderer( |
60 (self._get_image('human_1.png'), | 85 (self._get_image('human_1.png'), |
61 self._get_image('human_1.png'), | 86 self._get_image('human_1.png'), |
62 self._get_image('human_1.png'), | 87 self._get_image('human_1.png'), |
122 | 147 |
123 def get_render_angle(self): | 148 def get_render_angle(self): |
124 return self.angle | 149 return self.angle |
125 | 150 |
126 def go_werewolf(self): | 151 def go_werewolf(self): |
127 self._physicsers[self.form].remove_from_space() | 152 self.physicser.switch_form(self.form, self.WOLF_FORM) |
128 self.form = self.WOLF_FORM | 153 self.form = self.WOLF_FORM |
129 self._physicsers[self.form].add_to_space() | |
130 self.physicser = self._physicsers[self.form] | |
131 self._body.mass = 100 | |
132 self._body.velocity_limit = 1000 | |
133 self.impulse_factor = 4000 | 154 self.impulse_factor = 4000 |
134 self._body.damping = 0.9 | 155 |
135 if self.render_form == self.HUMAN_FORM: | 156 if self.render_form == self.HUMAN_FORM: |
136 self.render_form = self.WOLF_FORM | 157 self.render_form = self.WOLF_FORM |
137 elif self.render_form == self.HUMAN_FORM_BACK: | 158 elif self.render_form == self.HUMAN_FORM_BACK: |
138 self.render_form = self.WOLF_FORM_BACK | 159 self.render_form = self.WOLF_FORM_BACK |
139 else: | 160 else: |
140 self.render_form = self.WOLF_FORM | 161 self.render_form = self.WOLF_FORM |
141 self.renderer = self._renderers[self.render_form] | 162 self.renderer = self._renderers[self.render_form] |
142 | 163 |
143 def go_human(self): | 164 def go_human(self): |
144 self._physicsers[self.form].remove_from_space() | 165 self.physicser.switch_form(self.form, self.HUMAN_FORM) |
145 self.form = self.HUMAN_FORM | 166 self.form = self.HUMAN_FORM |
146 self._physicsers[self.form].add_to_space() | |
147 self.physicser = self._physicsers[self.form] | |
148 self._body.mass = 10 | |
149 self._body.velocity_limit = 1000 | |
150 self.impulse_factor = 500 | 167 self.impulse_factor = 500 |
151 self._body.damping = 0.8 | 168 |
152 if self.render_form == self.WOLF_FORM: | 169 if self.render_form == self.WOLF_FORM: |
153 self.render_form = self.HUMAN_FORM | 170 self.render_form = self.HUMAN_FORM |
154 elif self.render_form == self.WOLF_FORM_BACK: | 171 elif self.render_form == self.WOLF_FORM_BACK: |
155 self.render_form = self.HUMAN_FORM_BACK | 172 self.render_form = self.HUMAN_FORM_BACK |
156 else: | 173 else: |
184 # trigger a front/back swap and simplifies these checks | 201 # trigger a front/back swap and simplifies these checks |
185 if self.angle > 0 and old_angle != self.angle: | 202 if self.angle > 0 and old_angle != self.angle: |
186 self._switch_to_back() | 203 self._switch_to_back() |
187 elif self.angle < 0 and old_angle != self.angle: | 204 elif self.angle < 0 and old_angle != self.angle: |
188 self._switch_to_front() | 205 self._switch_to_front() |
189 self._body.apply_impulse( | 206 self.physicser.apply_impulse( |
190 (dx * self.impulse_factor, dy * self.impulse_factor)) | 207 (dx * self.impulse_factor, dy * self.impulse_factor)) |
191 self.renderer.start() | 208 self.renderer.start() |
192 | 209 |
193 def set_position(self, position): | 210 def set_position(self, position): |
194 self._body.position = position | 211 self.physicser.position = position |
195 | 212 |
196 def copy_state(self, old_protagonist): | 213 def copy_state(self, old_protagonist): |
197 self._physicsers[self.form].remove_from_space() | 214 self.physicser.position = old_protagonist.physicser.position |
198 self._body.position = old_protagonist._body.position | 215 self.physicser.switch_form(self.form, old_protagonist.form) |
199 self.form = old_protagonist.form | 216 self.form = old_protagonist.form |
200 self.angle = old_protagonist.angle | 217 self.angle = old_protagonist.angle |
201 self.render_form = old_protagonist.render_form | 218 self.render_form = old_protagonist.render_form |
202 self.inventory = old_protagonist.inventory | 219 self.inventory = old_protagonist.inventory |
203 self.renderer = self._renderers[self.render_form] | 220 self.renderer = self._renderers[self.render_form] |
204 self._physicsers[self.form].add_to_space() | |
205 self.physicser = self._physicsers[self.form] | |
206 | 221 |
207 def toggle_form(self): | 222 def toggle_form(self): |
208 if self.form == self.WOLF_FORM: | 223 if self.form == self.WOLF_FORM: |
209 self.go_human() | 224 self.go_human() |
210 else: | 225 else: |
231 return item in self.inventory | 246 return item in self.inventory |
232 | 247 |
233 def environmental_movement(self, dx, dy): | 248 def environmental_movement(self, dx, dy): |
234 if (dx, dy) == (0, 0): | 249 if (dx, dy) == (0, 0): |
235 return | 250 return |
236 self._body.apply_impulse((dx, dy)) | 251 self.physicser.apply_impulse((dx, dy)) |