# HG changeset patch # User Jeremy Thurgood # Date 1378113050 -7200 # Node ID d6a49f0c1e6ed146aa7d4e8ade97c6559d670bff # Parent 4c7e85906453541ad97d8de62145b0589189dc5a Rectangular human protagonist shape, refactored physicsers. diff -r 4c7e85906453 -r d6a49f0c1e6e nagslang/game_object.py --- a/nagslang/game_object.py Mon Sep 02 08:47:05 2013 +0200 +++ b/nagslang/game_object.py Mon Sep 02 11:10:50 2013 +0200 @@ -2,6 +2,7 @@ import pygame import pymunk +import pymunk.pygame_util from nagslang.constants import SWITCH_PUSHERS, COLLISION_TYPE_SWITCH @@ -15,48 +16,62 @@ class FloorSwitchPuzzler(Puzzler): - def __init__(self, shape): - self.shape = shape + def __init__(self, space, shape): + self._space = space + self._shape = shape - def get_state(self, space): - for shape in space.shape_query(self.shape): + def get_state(self): + for shape in self._space.shape_query(self._shape): if shape.collision_type in SWITCH_PUSHERS: return True return False class Physicser(object): - def add_to_space(self, space): + def __init__(self, space): + self.space = space + + def add_to_space(self): raise NotImplementedError() - def remove_from_space(self, space): + def remove_from_space(self): raise NotImplementedError() - def render_position(self, surface): + def get_render_position(self, surface): raise NotImplementedError() - def render_angle(self): + def get_angle(self): + raise NotImplementedError() + + def apply_impulse(self, j, r=(0, 0)): raise NotImplementedError() class SingleShapePhysicser(Physicser): - def __init__(self, shape): + def __init__(self, space, shape): + super(SingleShapePhysicser, self).__init__(space) self._shape = shape - def add_to_space(self, space): - space.add(self._shape, self._shape.body) + def add_to_space(self): + self.space.add(self._shape) + if not self._shape.body.is_static: + self.space.add(self._shape.body) - def remove_from_space(self, space): - space.remove(self._shape, self._shape.body) + def remove_from_space(self): + self.space.remove(self._shape) + if not self._shape.body.is_static: + self.space.remove(self._shape.body) - def render_position(self, surface): + def get_render_position(self, surface): pos = self._shape.body.position - import pymunk.pygame_util return pymunk.pygame_util.to_pygame(pos, surface) - def render_angle(self): + 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) + class Renderer(object): def render(self, surface, pos, angle): @@ -108,39 +123,39 @@ This has a rendery thing, physicsy things and maybe some other things. """ - def __init__(self, renderer, physicser, puzzler=None): + def __init__(self, physicser, renderer, puzzler=None): + self.physicser = physicser + self.physicser.add_to_space() self.renderer = renderer - self.physicser = physicser self.puzzler = puzzler - def add_to_space(self, space): - self.physicser.add_to_space(space) + def get_render_position(self, surface): + return self.physicser.get_render_position(surface) + + def get_render_angle(self): + return self.physicser.get_angle() def render(self, surface): return self.renderer.render( - surface, self.physicser.render_position(surface), - self.physicser.render_angle()) + surface, self.get_render_position(surface), + self.get_render_angle()) class FloorSwitch(GameObject): - def __init__(self, position): + def __init__(self, space, position): body = pymunk.Body() body.position = position self.shape = pymunk.Circle(body, 30) self.shape.collision_type = COLLISION_TYPE_SWITCH self.shape.sensor = True super(FloorSwitch, self).__init__( + SingleShapePhysicser(space, self.shape), ShapeRenderer(self.shape), - SingleShapePhysicser(self.shape), - FloorSwitchPuzzler(self.shape), + FloorSwitchPuzzler(space, self.shape), ) - def add_to_space(self, space): - # XXX: Hacky hack. - self._space = space - def render(self, surface): - if self.puzzler.get_state(self._space): + if self.puzzler.get_state(): self.shape.color = pygame.color.THECOLORS['green'] else: self.shape.color = pygame.color.THECOLORS['red'] diff -r 4c7e85906453 -r d6a49f0c1e6e nagslang/protagonist.py --- a/nagslang/protagonist.py Mon Sep 02 08:47:05 2013 +0200 +++ b/nagslang/protagonist.py Mon Sep 02 11:10:50 2013 +0200 @@ -17,26 +17,34 @@ HUMAN_FORM = 'human' WOLF_FORM = 'wolf' - def __init__(self, position): - self._setup_physics(position) + def __init__(self, space, position): + self._setup_physics(space, position) self._setup_renderers() self.inventory = {} self.form = self.HUMAN_FORM super(Protagonist, self).__init__( - self._renderers[self.form], SingleShapePhysicser(self.shape)) + self._physicsers[self.form], self._renderers[self.form]) self.go_human() - def _setup_physics(self, position): - self._body = pymunk.Body(10, 10000) + def _setup_physics(self, space, position): + self._body = pymunk.Body(10, pymunk.inf) self._body.position = position self._body.velocity_func = self.velocity_func - self.shape = pymunk.Circle(self._body, 30) - self.shape.elasticity = 1.0 - self.shape.friction = 10.0 - self.shape.collision_type = COLLISION_TYPE_PLAYER + 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), + } + self._physicsers = {} + for form, shape in self._shapes.iteritems(): + shape.elasticity = 1.0 + shape.friction = 10.0 + shape.collision_type = COLLISION_TYPE_PLAYER + self._physicsers[form] = SingleShapePhysicser(space, shape) + self.angle = 0 def _get_image(self, name, *transforms): return resources.get_image('creatures', name, transforms=transforms) @@ -62,19 +70,24 @@ def velocity_func(self, body, gravity, damping, dt): return pymunk.Body.update_velocity(body, gravity, self.damping, dt) + def get_render_angle(self): + return self.angle + def go_werewolf(self): + self._physicsers[self.form].remove_from_space() self.form = self.WOLF_FORM + self._physicsers[self.form].add_to_space() self._body.mass = 100 - self._body.moment = 10000 self._body.velocity_limit = 1000 self.impulse_factor = 4000 self.damping = 0.9 self.renderer = self._renderers[self.form] def go_human(self): + self._physicsers[self.form].remove_from_space() self.form = self.HUMAN_FORM + self._physicsers[self.form].add_to_space() self._body.mass = 10 - self._body.moment = 1000 self._body.velocity_limit = 1000 self.impulse_factor = 500 self.damping = 0.8 @@ -83,8 +96,7 @@ def set_direction(self, dx, dy): if (dx, dy) == (0, 0): return - vec = pymunk.Vec2d((dx, dy)) - self._body.angle = vec.angle + self.angle = pymunk.Vec2d((dx, dy)).angle self._body.apply_impulse( (dx * self.impulse_factor, dy * self.impulse_factor)) @@ -118,3 +130,7 @@ if (dx, dy) == (0, 0): return self._body.apply_impulse((dx, dy)) + + def render(self, surface): + pymunk.pygame_util.draw(surface, self._shapes[self.form]) + super(Protagonist, self).render(surface) diff -r 4c7e85906453 -r d6a49f0c1e6e nagslang/screens/area.py --- a/nagslang/screens/area.py Mon Sep 02 08:47:05 2013 +0200 +++ b/nagslang/screens/area.py Mon Sep 02 11:10:50 2013 +0200 @@ -53,10 +53,8 @@ self.space.add(*self.walls) def add_protagonist(self): - self.protagonist = Protagonist((350, 300)) - self.protagonist.add_to_space(self.space) - self.toy_switch = FloorSwitch((300, 400)) - self.toy_switch.add_to_space(self.space) + self.protagonist = Protagonist(self.space, (350, 300)) + self.toy_switch = FloorSwitch(self.space, (300, 400)) def handle_event(self, ev): if ev.type == pygame.locals.KEYDOWN: @@ -69,7 +67,7 @@ def _calc_viewport(self, level_surface, display_surface): level_size = level_surface.get_size() display_size = display_surface.get_size() - protagnist_pos = self.protagonist.physicser.render_position( + protagnist_pos = self.protagonist.physicser.get_render_position( level_surface) x_wide = display_size[0] // 2 y_wide = display_size[1] // 2