changeset 180:026297a03963

Add DoorEvent and tweak ScreenChange to keep more state when the player goes through a door
author Neil Muller <drnlmuller@gmail.com>
date Tue, 03 Sep 2013 16:58:45 +0200
parents 1ee8756888e4
children 0e5bae238a92
files nagslang/engine.py nagslang/events.py nagslang/game_object.py nagslang/screens/area.py nagslang/screens/base.py nagslang/screens/menu.py
diffstat 6 files changed, 33 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/nagslang/engine.py	Tue Sep 03 16:57:09 2013 +0200
+++ b/nagslang/engine.py	Tue Sep 03 16:58:45 2013 +0200
@@ -22,17 +22,17 @@
             'level1': AreaScreen,
             'level2': AreaScreen,
         }
-        self.change_screen('menu')
+        self.change_screen('menu', None)
         # Dummy resize event, to force us to realise our real size
         # http://stackoverflow.com/q/16442573/8629
         pygame.event.post(pygame.event.Event(pgl.VIDEORESIZE,
                                              size=(0, 0), w=0, h=0))
 
-    def change_screen(self, new_screen):
+    def change_screen(self, new_screen, player):
         if self._current_screen is not None:
             self._current_screen.teardown()
         screen_cls = self._screens[new_screen]
-        self._current_screen = screen_cls(new_screen, self._world)
+        self._current_screen = screen_cls(new_screen, player, self._world)
         self._current_screen.setup()
 
     def run(self):
@@ -47,7 +47,7 @@
                     self._surface = pygame.display.get_surface()
                 elif ScreenChange.matches(ev):
                     self._surface.fill(pygame.color.Color(0, 0, 0))
-                    self.change_screen(ev.screen)
+                    self.change_screen(ev.screen, ev.player)
                 else:
                     self._current_screen.handle_event(ev)
             self._current_screen.tick(self._dt)
--- a/nagslang/events.py	Tue Sep 03 16:57:09 2013 +0200
+++ b/nagslang/events.py	Tue Sep 03 16:58:45 2013 +0200
@@ -35,5 +35,11 @@
 
 class ScreenChange(UserEvent):
     @classmethod
-    def post(cls, new_screen):
-        super(ScreenChange, cls).post(screen=new_screen)
+    def post(cls, new_screen, player=None):
+        super(ScreenChange, cls).post(screen=new_screen, player=player)
+
+
+class DoorEvent(UserEvent):
+    @classmethod
+    def post(cls, destination, dest_pos):
+        super(DoorEvent, cls).post(destination=destination, dest_pos=dest_pos)
--- a/nagslang/game_object.py	Tue Sep 03 16:57:09 2013 +0200
+++ b/nagslang/game_object.py	Tue Sep 03 16:58:45 2013 +0200
@@ -9,7 +9,7 @@
     ZORDER_FLOOR, COLLISION_TYPE_DOOR, COLLISION_TYPE_PLAYER)
 from nagslang.options import options
 from nagslang.resources import resources
-from nagslang.events import ScreenChange
+from nagslang.events import DoorEvent
 
 
 class PuzzleGlue(object):
@@ -406,5 +406,4 @@
         for shape in space.shape_query(self.get_shape()):
             if shape.collision_type == COLLISION_TYPE_PLAYER:
                 # Force to new position
-                shape.body.position = self.dest_pos
-                ScreenChange.post(self.destination)
+                DoorEvent.post(self.destination, self.dest_pos)
--- a/nagslang/screens/area.py	Tue Sep 03 16:57:09 2013 +0200
+++ b/nagslang/screens/area.py	Tue Sep 03 16:58:45 2013 +0200
@@ -4,7 +4,7 @@
 import pymunk
 import pymunk.pygame_util
 
-from nagslang.events import ScreenChange
+from nagslang.events import ScreenChange, DoorEvent
 from nagslang.level import Level
 from nagslang.protagonist import Protagonist
 from nagslang.screens.base import Screen
@@ -68,7 +68,14 @@
         self._level.load(self.space)
         self._drawables = Drawables()
         self.add_walls()
-        self.add_protagonist()
+        if self.protagonist is not None:
+            # We do things this way to avoid extra pymunk
+            # juggling to move objects between spaces
+            old_protagonist = self.protagonist
+            self.add_protagonist()
+            self.protagonist.copy_state(old_protagonist)
+        else:
+            self.add_protagonist()
         self.add_game_objects()
 
     def add_walls(self):
@@ -100,6 +107,13 @@
                 ScreenChange.post('menu')
             if ev.key == pygame.locals.K_c:
                 self.protagonist.toggle_form()
+        elif DoorEvent.matches(ev):
+            self.protagonist.set_position(ev.dest_pos)
+            if ev.destination != self.name:
+                # Go to anther screen
+                ScreenChange.post(ev.destination, self.protagonist)
+            # else we're teleporting within the screen, and just the
+            # position change is enough
         self.keys.handle_event(ev)
 
     def _calc_viewport(self, level_surface, display_surface):
--- a/nagslang/screens/base.py	Tue Sep 03 16:57:09 2013 +0200
+++ b/nagslang/screens/base.py	Tue Sep 03 16:58:45 2013 +0200
@@ -6,9 +6,10 @@
 
 class Screen(object):
 
-    def __init__(self, name, world):
+    def __init__(self, name, player, world):
         self.name = name
         self.world = world
+        self.protagonist = player
         self.space = pymunk.Space()
 
     def setup(self):
--- a/nagslang/screens/menu.py	Tue Sep 03 16:57:09 2013 +0200
+++ b/nagslang/screens/menu.py	Tue Sep 03 16:58:45 2013 +0200
@@ -14,7 +14,7 @@
             if ev.key == pygame.locals.K_ESCAPE:
                 QuitEvent.post()
             elif ev.key == pygame.locals.K_1:
-                ScreenChange.post('level1')
+                ScreenChange.post('level1', None)
 
     def render(self, surface):
         surface.fill(pygame.color.Color(255, 255, 255))