Mercurial > nagslang
changeset 215:325c317cbfa1
Better protagonist physicser.
author | Jeremy Thurgood <firxen@gmail.com> |
---|---|
date | Wed, 04 Sep 2013 13:13:11 +0200 |
parents | d3d602a527bd |
children | f23ab2dd6ce8 |
files | nagslang/game_object.py nagslang/protagonist.py |
diffstat | 2 files changed, 71 insertions(+), 61 deletions(-) [+] |
line wrap: on
line diff
--- a/nagslang/game_object.py Wed Sep 04 01:14:49 2013 +0200 +++ b/nagslang/game_object.py Wed Sep 04 13:13:11 2013 +0200 @@ -25,19 +25,34 @@ raise NotImplementedError() def add_to_space(self): - raise NotImplementedError() + shape = self.get_shape() + self.get_space().add(shape) + if not shape.body.is_static: + self.get_space().add(shape.body) def remove_from_space(self): - raise NotImplementedError() + shape = self.get_shape() + self.get_space().remove(shape) + if not shape.body.is_static: + self.get_space().remove(shape.body) def get_render_position(self, surface): - raise NotImplementedError() + pos = self.get_shape().body.position + return pymunk.pygame_util.to_pygame(pos, surface) def get_angle(self): - raise NotImplementedError() + return self.get_shape().body.angle + + @property + def position(self): + return self.get_shape().body.position + + @position.setter + def position(self, position): + self.get_shape().body.position = position def apply_impulse(self, j, r=(0, 0)): - raise NotImplementedError() + return self.get_shape().body.apply_impulse(j, r) class SingleShapePhysicser(Physicser): @@ -49,26 +64,6 @@ def get_shape(self): return self._shape - def add_to_space(self): - self.get_space().add(self._shape) - if not self._shape.body.is_static: - self.get_space().add(self._shape.body) - - def remove_from_space(self): - self.get_space().remove(self._shape) - if not self._shape.body.is_static: - self.get_space().remove(self._shape.body) - - def get_render_position(self, surface): - pos = self._shape.body.position - return pymunk.pygame_util.to_pygame(pos, surface) - - def get_angle(self): - return self._shape.body.angle - - def apply_impulse(self, j, r=(0, 0)): - return self._shape.body.apply_impulse(j, r) - def damping_velocity_func(body, gravity, damping, dt): """Apply custom damping to this body's velocity.
--- a/nagslang/protagonist.py Wed Sep 04 01:14:49 2013 +0200 +++ b/nagslang/protagonist.py Wed Sep 04 13:13:11 2013 +0200 @@ -5,11 +5,27 @@ from nagslang import render from nagslang.constants import COLLISION_TYPE_PLAYER, ZORDER_MID -from nagslang.game_object import GameObject, SingleShapePhysicser, make_body +from nagslang.game_object import GameObject, Physicser, make_body from nagslang.mutators import FLIP_H from nagslang.resources import resources +class ProtagonistPhysicser(Physicser): + def __init__(self, space, form_shapes): + self._space = space + self._form_shapes = form_shapes + + def switch_form(self, old_form, new_form): + self._space.remove(self._form_shapes[old_form]) + shape = self._form_shapes[new_form] + self._space.add(shape) + for attr, value in shape.protagonist_body_props.iteritems(): + setattr(shape.body, attr, value) + + def get_shape(self): + return self._form_shapes[self.game_object.form] + + class Protagonist(GameObject): """Representation of our fearless protagonist. @@ -22,39 +38,48 @@ WOLF_FORM_BACK = 'wolf_back' def __init__(self, space, position): - self._setup_physics(space, position) + physicser = self._make_physics(space, position) self._setup_renderers() self.inventory = {} self.form = self.HUMAN_FORM self.render_form = self.HUMAN_FORM super(Protagonist, self).__init__( - self._physicsers[self.form], self._renderers[self.form]) + physicser, self._renderers[self.form]) self.zorder = ZORDER_MID self.go_human() - def _setup_physics(self, space, position): - self._body = make_body(10, pymunk.inf, position, 0.8) + def _make_physics(self, space, position): + body = make_body(10, pymunk.inf, position, 0.8) + body.velocity_limit = 1000 - self._shapes = { - self.HUMAN_FORM: pymunk.Poly( - self._body, [(-15, -30), (15, -30), (15, 30), (-15, 30)]), - self.WOLF_FORM: pymunk.Circle(self._body, 30), + human = pymunk.Poly(body, [(-15, -30), (15, -30), (15, 30), (-15, 30)]) + human.elasticity = 1.0 + human.collision_type = COLLISION_TYPE_PLAYER + human.protagonist_body_props = { + 'mass': 10, + 'damping': 0.8, } - self._shapes[self.HUMAN_FORM].friction = 1.0 - self._shapes[self.WOLF_FORM].friction = 0.05 - self._physicsers = {} - for form, shape in self._shapes.iteritems(): - shape.elasticity = 1.0 - shape.collision_type = COLLISION_TYPE_PLAYER - self._physicsers[form] = SingleShapePhysicser(space, shape) - self.angle = 0 + + wolf = pymunk.Circle(body, 30) + wolf.elasticity = 1.0 + wolf.collision_type = COLLISION_TYPE_PLAYER + wolf.protagonist_body_props = { + 'mass': 100, + 'damping': 0.9, + } + + return ProtagonistPhysicser(space, { + self.HUMAN_FORM: human, + self.WOLF_FORM: wolf, + }) def _get_image(self, name, *transforms): return resources.get_image('creatures', name, transforms=transforms) def _setup_renderers(self): + self.angle = 0 self._renderers = { self.HUMAN_FORM: render.AnimatedFacingImageRenderer( (self._get_image('human_1.png'), @@ -124,14 +149,10 @@ return self.angle def go_werewolf(self): - self._physicsers[self.form].remove_from_space() + self.physicser.switch_form(self.form, self.WOLF_FORM) self.form = self.WOLF_FORM - self._physicsers[self.form].add_to_space() - self.physicser = self._physicsers[self.form] - self._body.mass = 100 - self._body.velocity_limit = 1000 self.impulse_factor = 4000 - self._body.damping = 0.9 + if self.render_form == self.HUMAN_FORM: self.render_form = self.WOLF_FORM elif self.render_form == self.HUMAN_FORM_BACK: @@ -141,14 +162,10 @@ self.renderer = self._renderers[self.render_form] def go_human(self): - self._physicsers[self.form].remove_from_space() + self.physicser.switch_form(self.form, self.HUMAN_FORM) self.form = self.HUMAN_FORM - self._physicsers[self.form].add_to_space() - self.physicser = self._physicsers[self.form] - self._body.mass = 10 - self._body.velocity_limit = 1000 self.impulse_factor = 500 - self._body.damping = 0.8 + if self.render_form == self.WOLF_FORM: self.render_form = self.HUMAN_FORM elif self.render_form == self.WOLF_FORM_BACK: @@ -186,23 +203,21 @@ self._switch_to_back() elif self.angle < 0 and old_angle != self.angle: self._switch_to_front() - self._body.apply_impulse( + self.physicser.apply_impulse( (dx * self.impulse_factor, dy * self.impulse_factor)) self.renderer.start() def set_position(self, position): - self._body.position = position + self.physicser.position = position def copy_state(self, old_protagonist): - self._physicsers[self.form].remove_from_space() - self._body.position = old_protagonist._body.position + self.physicser.position = old_protagonist.physicser.position + self.physicser.switch_form(self.form, old_protagonist.form) self.form = old_protagonist.form self.angle = old_protagonist.angle self.render_form = old_protagonist.render_form self.inventory = old_protagonist.inventory self.renderer = self._renderers[self.render_form] - self._physicsers[self.form].add_to_space() - self.physicser = self._physicsers[self.form] def toggle_form(self): if self.form == self.WOLF_FORM: @@ -233,4 +248,4 @@ def environmental_movement(self, dx, dy): if (dx, dy) == (0, 0): return - self._body.apply_impulse((dx, dy)) + self.physicser.apply_impulse((dx, dy))