# HG changeset patch # User Jeremy Thurgood # Date 1378231572 -7200 # Node ID d63c19003aecefb0e470aef2b46eae5bae264c63 # Parent dfacd08b8566d2ceb752945ad9c086a5df596732 Some refactoring and fixing, start of better collision handling. diff -r dfacd08b8566 -r d63c19003aec nagslang/constants.py --- a/nagslang/constants.py Tue Sep 03 19:48:02 2013 +0200 +++ b/nagslang/constants.py Tue Sep 03 20:06:12 2013 +0200 @@ -18,6 +18,15 @@ SWITCH_PUSHERS = [COLLISION_TYPE_PLAYER, COLLISION_TYPE_BOX] +CALLBACK_COLLIDERS = [ + # Collisions between the player and shapes with these collision types will + # fire callbacks on the game object associated with the shape. + COLLISION_TYPE_SWITCH, + COLLISION_TYPE_BOX, + COLLISION_TYPE_ENEMY, + COLLISION_TYPE_DOOR, +] + ZORDER_FLOOR = 0 ZORDER_LOW = 1 ZORDER_MID = 2 diff -r dfacd08b8566 -r d63c19003aec nagslang/events.py --- a/nagslang/events.py Tue Sep 03 19:48:02 2013 +0200 +++ b/nagslang/events.py Tue Sep 03 20:06:12 2013 +0200 @@ -1,6 +1,7 @@ """Events to post.""" import pygame +import pygame.locals class Event(object): diff -r dfacd08b8566 -r d63c19003aec nagslang/game_object.py --- a/nagslang/game_object.py Tue Sep 03 19:48:02 2013 +0200 +++ b/nagslang/game_object.py Tue Sep 03 20:06:12 2013 +0200 @@ -41,6 +41,20 @@ raise NotImplementedError() +class YesPuzzler(Puzzler): + """Yes sir, I'm always on. + """ + def get_state(self): + return True + + +class NoPuzzler(Puzzler): + """No sir, I'm always off. + """ + def get_state(self): + return False + + class CollidePuzzler(Puzzler): def __init__(self, *collision_types): if not collision_types: @@ -107,6 +121,7 @@ def __init__(self, space, shape): super(SingleShapePhysicser, self).__init__(space) self._shape = shape + shape.physicser = self def get_shape(self): return self._shape @@ -341,6 +356,14 @@ def animate(self): self.renderer.animate() + def collide_with_protagonist(self): + """Called as a `pre_solve` collision callback with the protagonist. + + You can return `False` to ignore the collision, anything else + (including `None`) to process the collision as normal. + """ + pass + class FloorSwitch(GameObject): zorder = ZORDER_FLOOR @@ -393,7 +416,7 @@ class Door(GameObject): zorder = ZORDER_FLOOR - def __init__(self, space, position, destination, dest_pos): + def __init__(self, space, position, destination, dest_pos, key_state=None): body = make_body(pymunk.inf, pymunk.inf, position, damping=0.5) self.shape = pymunk.Poly( body, [(-32, -32), (32, -32), (32, 32), (-32, 32)]) @@ -401,9 +424,14 @@ self.shape.sensor = True self.destination = destination self.dest_pos = tuple(dest_pos) + if key_state is None: + puzzler = YesPuzzler() + else: + puzzler = StateProxyPuzzler(key_state) super(Door, self).__init__( SingleShapePhysicser(space, self.shape), ImageRenderer(resources.get_image('objects', 'door.png')), + puzzler, ) def animate(self): diff -r dfacd08b8566 -r d63c19003aec nagslang/tests/test_game_object.py --- a/nagslang/tests/test_game_object.py Tue Sep 03 19:48:02 2013 +0200 +++ b/nagslang/tests/test_game_object.py Tue Sep 03 20:06:12 2013 +0200 @@ -43,19 +43,21 @@ puzzler.set_game_object(gobj) return puzzler - def assert_floor_switch(self, expected, shapes): + def assert_collide_state(self, expected, shapes, collision_types): gobj = FakeGameObject(None, FakeSpace(*shapes)) - puzzler = self.mkpuzzler(gobj, game_object.FloorSwitchPuzzler) + puzzler = self.mkpuzzler( + gobj, game_object.CollidePuzzler, *collision_types) self.assertEqual(expected, puzzler.get_state()) - def test_floor_switch_puzzler(self): - self.assert_floor_switch(False, []) - self.assert_floor_switch(False, [FakeShape()]) + def test_collide_puzzler(self): + self.assert_collide_state(False, [], []) + self.assert_collide_state(False, [FakeShape()], SWITCH_PUSHERS) for collision_type in SWITCH_PUSHERS: - self.assert_floor_switch(True, [FakeShape(collision_type)]) - self.assert_floor_switch( - True, [FakeShape(), FakeShape(collision_type)]) + self.assert_collide_state( + True, [FakeShape(collision_type)], SWITCH_PUSHERS) + self.assert_collide_state( + True, [FakeShape(), FakeShape(collision_type)], SWITCH_PUSHERS) def test_state_proxy_puzzler(self): glue = game_object.PuzzleGlue() diff -r dfacd08b8566 -r d63c19003aec nagslang/tests/test_level.py --- a/nagslang/tests/test_level.py Tue Sep 03 19:48:02 2013 +0200 +++ b/nagslang/tests/test_level.py Tue Sep 03 20:06:12 2013 +0200 @@ -78,8 +78,7 @@ self.assertTrue( isinstance(puzzle_bits['foo_proxy'], go.StateProxyPuzzler)) self.assertEqual('foo', puzzle_bits['foo_proxy']._state_source) - self.assertTrue(isinstance(puzzle_bits['foo'], - go.FloorSwitchPuzzler)) + self.assertTrue(isinstance(puzzle_bits['foo'], go.CollidePuzzler)) level = self.make_level('foo', { 'size': [5, 10],