Changeset 215:325c317cbfa1


Ignore:
Timestamp:
Sep 4, 2013, 11:13:11 AM (7 years ago)
Author:
Jeremy Thurgood <firxen@…>
Branch:
default
Message:

Better protagonist physicser.

Location:
nagslang
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • nagslang/game_object.py

    r211 r215  
    2626
    2727    def add_to_space(self):
    28         raise NotImplementedError()
     28        shape = self.get_shape()
     29        self.get_space().add(shape)
     30        if not shape.body.is_static:
     31            self.get_space().add(shape.body)
    2932
    3033    def remove_from_space(self):
    31         raise NotImplementedError()
     34        shape = self.get_shape()
     35        self.get_space().remove(shape)
     36        if not shape.body.is_static:
     37            self.get_space().remove(shape.body)
    3238
    3339    def get_render_position(self, surface):
    34         raise NotImplementedError()
     40        pos = self.get_shape().body.position
     41        return pymunk.pygame_util.to_pygame(pos, surface)
    3542
    3643    def get_angle(self):
    37         raise NotImplementedError()
     44        return self.get_shape().body.angle
     45
     46    @property
     47    def position(self):
     48        return self.get_shape().body.position
     49
     50    @position.setter
     51    def position(self, position):
     52        self.get_shape().body.position = position
    3853
    3954    def apply_impulse(self, j, r=(0, 0)):
    40         raise NotImplementedError()
     55        return self.get_shape().body.apply_impulse(j, r)
    4156
    4257
     
    4964    def get_shape(self):
    5065        return self._shape
    51 
    52     def add_to_space(self):
    53         self.get_space().add(self._shape)
    54         if not self._shape.body.is_static:
    55             self.get_space().add(self._shape.body)
    56 
    57     def remove_from_space(self):
    58         self.get_space().remove(self._shape)
    59         if not self._shape.body.is_static:
    60             self.get_space().remove(self._shape.body)
    61 
    62     def get_render_position(self, surface):
    63         pos = self._shape.body.position
    64         return pymunk.pygame_util.to_pygame(pos, surface)
    65 
    66     def get_angle(self):
    67         return self._shape.body.angle
    68 
    69     def apply_impulse(self, j, r=(0, 0)):
    70         return self._shape.body.apply_impulse(j, r)
    7166
    7267
  • nagslang/protagonist.py

    r208 r215  
    66from nagslang import render
    77from nagslang.constants import COLLISION_TYPE_PLAYER, ZORDER_MID
    8 from nagslang.game_object import GameObject, SingleShapePhysicser, make_body
     8from nagslang.game_object import GameObject, Physicser, make_body
    99from nagslang.mutators import FLIP_H
    1010from nagslang.resources import resources
     11
     12
     13class 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]
    1127
    1228
     
    2339
    2440    def __init__(self, space, position):
    25         self._setup_physics(space, position)
     41        physicser = self._make_physics(space, position)
    2642        self._setup_renderers()
    2743        self.inventory = {}
     
    3046
    3147        super(Protagonist, self).__init__(
    32             self._physicsers[self.form], self._renderers[self.form])
     48            physicser, self._renderers[self.form])
    3349        self.zorder = ZORDER_MID
    3450
    3551        self.go_human()
    3652
    37     def _setup_physics(self, space, position):
    38         self._body = make_body(10, pymunk.inf, position, 0.8)
    39 
    40         self._shapes = {
    41             self.HUMAN_FORM: pymunk.Poly(
    42                 self._body, [(-15, -30), (15, -30), (15, 30), (-15, 30)]),
    43             self.WOLF_FORM: pymunk.Circle(self._body, 30),
     53    def _make_physics(self, space, position):
     54        body = make_body(10, pymunk.inf, position, 0.8)
     55        body.velocity_limit = 1000
     56
     57        human = pymunk.Poly(body, [(-15, -30), (15, -30), (15, 30), (-15, 30)])
     58        human.elasticity = 1.0
     59        human.collision_type = COLLISION_TYPE_PLAYER
     60        human.protagonist_body_props = {
     61            'mass': 10,
     62            'damping': 0.8,
    4463        }
    45         self._shapes[self.HUMAN_FORM].friction = 1.0
    46         self._shapes[self.WOLF_FORM].friction = 0.05
    47         self._physicsers = {}
    48         for form, shape in self._shapes.iteritems():
    49             shape.elasticity = 1.0
    50             shape.collision_type = COLLISION_TYPE_PLAYER
    51             self._physicsers[form] = SingleShapePhysicser(space, shape)
    52         self.angle = 0
     64
     65        wolf = pymunk.Circle(body, 30)
     66        wolf.elasticity = 1.0
     67        wolf.collision_type = COLLISION_TYPE_PLAYER
     68        wolf.protagonist_body_props = {
     69            'mass': 100,
     70            'damping': 0.9,
     71        }
     72
     73        return ProtagonistPhysicser(space, {
     74            self.HUMAN_FORM: human,
     75            self.WOLF_FORM: wolf,
     76        })
    5377
    5478    def _get_image(self, name, *transforms):
     
    5680
    5781    def _setup_renderers(self):
     82        self.angle = 0
    5883        self._renderers = {
    5984            self.HUMAN_FORM: render.AnimatedFacingImageRenderer(
     
    125150
    126151    def go_werewolf(self):
    127         self._physicsers[self.form].remove_from_space()
     152        self.physicser.switch_form(self.form, self.WOLF_FORM)
    128153        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
    133154        self.impulse_factor = 4000
    134         self._body.damping = 0.9
     155
    135156        if self.render_form == self.HUMAN_FORM:
    136157            self.render_form = self.WOLF_FORM
     
    142163
    143164    def go_human(self):
    144         self._physicsers[self.form].remove_from_space()
     165        self.physicser.switch_form(self.form, self.HUMAN_FORM)
    145166        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
    150167        self.impulse_factor = 500
    151         self._body.damping = 0.8
     168
    152169        if self.render_form == self.WOLF_FORM:
    153170            self.render_form = self.HUMAN_FORM
     
    187204            elif self.angle < 0 and old_angle != self.angle:
    188205                self._switch_to_front()
    189         self._body.apply_impulse(
     206        self.physicser.apply_impulse(
    190207            (dx * self.impulse_factor, dy * self.impulse_factor))
    191208        self.renderer.start()
    192209
    193210    def set_position(self, position):
    194         self._body.position = position
     211        self.physicser.position = position
    195212
    196213    def copy_state(self, old_protagonist):
    197         self._physicsers[self.form].remove_from_space()
    198         self._body.position = old_protagonist._body.position
     214        self.physicser.position = old_protagonist.physicser.position
     215        self.physicser.switch_form(self.form, old_protagonist.form)
    199216        self.form = old_protagonist.form
    200217        self.angle = old_protagonist.angle
     
    202219        self.inventory = old_protagonist.inventory
    203220        self.renderer = self._renderers[self.render_form]
    204         self._physicsers[self.form].add_to_space()
    205         self.physicser = self._physicsers[self.form]
    206221
    207222    def toggle_form(self):
     
    234249        if (dx, dy) == (0, 0):
    235250            return
    236         self._body.apply_impulse((dx, dy))
     251        self.physicser.apply_impulse((dx, dy))
Note: See TracChangeset for help on using the changeset viewer.