diff nagslang/game_object.py @ 123:23b533d6f27e

Rearrange game objects a bit.
author Jeremy Thurgood <firxen@gmail.com>
date Mon, 02 Sep 2013 16:43:15 +0200
parents b90d01e4d9d4
children c3af35561494
line wrap: on
line diff
--- a/nagslang/game_object.py	Mon Sep 02 16:40:56 2013 +0200
+++ b/nagslang/game_object.py	Mon Sep 02 16:43:15 2013 +0200
@@ -29,17 +29,17 @@
     def set_glue(self, glue):
         self.glue = glue
 
+    def set_game_object(self, game_object):
+        self.game_object = game_object
+
     def get_state(self):
         raise NotImplementedError()
 
 
 class FloorSwitchPuzzler(Puzzler):
-    def __init__(self, space, shape):
-        self._space = space
-        self._shape = shape
-
     def get_state(self):
-        for shape in self._space.shape_query(self._shape):
+        space = self.game_object.get_space()
+        for shape in space.shape_query(self.game_object.get_shape()):
             if shape.collision_type in SWITCH_PUSHERS:
                 return True
         return False
@@ -55,7 +55,16 @@
 
 class Physicser(object):
     def __init__(self, space):
-        self.space = space
+        self._space = space
+
+    def get_space(self):
+        return self._space
+
+    def set_game_object(self, game_object):
+        self.game_object = game_object
+
+    def get_shape(self):
+        raise NotImplementedError()
 
     def add_to_space(self):
         raise NotImplementedError()
@@ -78,15 +87,18 @@
         super(SingleShapePhysicser, self).__init__(space)
         self._shape = shape
 
+    def get_shape(self):
+        return self._shape
+
     def add_to_space(self):
-        self.space.add(self._shape)
+        self.get_space().add(self._shape)
         if not self._shape.body.is_static:
-            self.space.add(self._shape.body)
+            self.get_space().add(self._shape.body)
 
     def remove_from_space(self):
-        self.space.remove(self._shape)
+        self.get_space().remove(self._shape)
         if not self._shape.body.is_static:
-            self.space.remove(self._shape.body)
+            self.get_space().remove(self._shape.body)
 
     def get_render_position(self, surface):
         pos = self._shape.body.position
@@ -100,29 +112,30 @@
 
 
 class Renderer(object):
-    def __init__(self, shape):
-        self._shape = shape
+    def set_game_object(self, game_object):
+        self.game_object = game_object
 
-    def _render_shape(self, surface, pos, angle):
+    def _render_shape(self, surface):
+        shape = self.game_object.get_shape()
         # Less general that pymunk.pygame_util.draw, but also a lot less noisy.
-        color = getattr(
-            self._shape, 'color', pygame.color.THECOLORS['lightblue'])
+        color = getattr(shape, 'color', pygame.color.THECOLORS['lightblue'])
         # We only explicitly draw Circle and Poly shapes. Everything else we
         # forward to pymunk.
-        if isinstance(self._shape, pymunk.Circle):
-            centre = pymunk.pygame_util.to_pygame(
-                self._shape.body.position, surface)
-            radius = int(self._shape.radius)
+        if isinstance(shape, pymunk.Circle):
+            centre = pymunk.pygame_util.to_pygame(shape.body.position, surface)
+            radius = int(shape.radius)
             pygame.draw.circle(surface, color, centre, radius, 2)
-        elif isinstance(self._shape, pymunk.Poly):
+        elif isinstance(shape, pymunk.Poly):
             # polygon bounding box
             points = [pymunk.pygame_util.to_pygame(p, surface)
-                      for p in self._shape.get_vertices()]
+                      for p in shape.get_vertices()]
             pygame.draw.lines(surface, color, True, points, 2)
         else:
-            pymunk.pygame_util.draw(surface, self._shape)
+            pymunk.pygame_util.draw(surface, shape)
 
-    def render(self, surface, pos, angle):
+    def render(self, surface):
+        pos = self.game_object.get_render_position(surface)
+        angle = self.game_object.get_render_angle()
         if options.debug:
             self._render_shape(surface, pos, angle)
 
@@ -133,18 +146,17 @@
 
 
 class ImageRenderer(Renderer):
-    def __init__(self, shape, image):
-        super(ImageRenderer, self).__init__(shape)
+    def __init__(self, image):
         self._image = image
 
-    def render(self, surface, pos, angle):
+    def render(self, surface):
+        pos = self.game_object.get_render_position(surface)
         surface.blit(self._image, image_pos(self._image, pos))
-        super(ImageRenderer, self).render(surface, pos, angle)
+        super(ImageRenderer, self).render(surface)
 
 
 class FacingImageRenderer(Renderer):
-    def __init__(self, shape, left_image, right_image):
-        super(FacingImageRenderer, self).__init__(shape)
+    def __init__(self, left_image, right_image):
         self._images = {
             'left': left_image,
             'right': right_image,
@@ -155,16 +167,17 @@
             return self._images['right']
         return self._images['left']
 
-    def render(self, surface, pos, angle):
-        image = self.get_image(angle)
+    def render(self, surface):
+        pos = self.game_object.get_render_position(surface)
+        image = self.get_image(self.game_object.get_render_angle())
         surface.blit(image, image_pos(image, pos))
-        super(FacingImageRenderer, self).render(surface, pos, angle)
+        super(FacingImageRenderer, self).render(surface)
 
 
 class ShapeRenderer(Renderer):
-    def render(self, surface, pos, angle):
-        self._render_shape(surface, pos, angle)
-        super(ShapeRenderer, self).render(surface, pos, angle)
+    def render(self, surface):
+        self._render_shape(surface)
+        super(ShapeRenderer, self).render(surface)
 
 
 class GameObject(object):
@@ -175,11 +188,21 @@
 
     def __init__(self, physicser, renderer, puzzler=None):
         self.physicser = physicser
+        physicser.set_game_object(self)
         self.physicser.add_to_space()
         self.renderer = renderer
+        renderer.set_game_object(self)
         self.puzzler = puzzler
+        if puzzler is not None:
+            puzzler.set_game_object(self)
         self.zorder = ZORDER_LOW
 
+    def get_space(self):
+        return self.physicser.get_space()
+
+    def get_shape(self):
+        return self.physicser.get_shape()
+
     def get_render_position(self, surface):
         return self.physicser.get_render_position(surface)
 
@@ -187,9 +210,7 @@
         return self.physicser.get_angle()
 
     def render(self, surface):
-        return self.renderer.render(
-            surface, self.get_render_position(surface),
-            self.get_render_angle())
+        return self.renderer.render(surface)
 
 
 class FloorSwitch(GameObject):
@@ -201,8 +222,8 @@
         self.shape.sensor = True
         super(FloorSwitch, self).__init__(
             SingleShapePhysicser(space, self.shape),
-            ShapeRenderer(self.shape),
-            FloorSwitchPuzzler(space, self.shape),
+            ShapeRenderer(),
+            FloorSwitchPuzzler(),
         )
 
     def render(self, surface):
@@ -222,7 +243,7 @@
         self.shape.sensor = True
         super(FloorLight, self).__init__(
             SingleShapePhysicser(space, self.shape),
-            ShapeRenderer(self.shape),
+            ShapeRenderer(),
             StateProxyPuzzler(state_source),
         )