changeset 385:51deb78cae52

Use a result object to get new drawables back to the area
author Stefano Rivera <stefano@rivera.za.net>
date Fri, 06 Sep 2013 23:58:15 +0200
parents 9efc1ab833c8
children 6daf48763bc0
files nagslang/collectable.py nagslang/enemies.py nagslang/game_object.py nagslang/screens/area.py
diffstat 4 files changed, 37 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/nagslang/collectable.py	Fri Sep 06 23:47:44 2013 +0200
+++ b/nagslang/collectable.py	Fri Sep 06 23:58:15 2013 +0200
@@ -3,7 +3,8 @@
 from nagslang import environment
 from nagslang import render
 from nagslang.constants import ZORDER_LOW
-from nagslang.game_object import GameObject, SingleShapePhysicser, make_body
+from nagslang.game_object import (GameObject, SingleShapePhysicser, Result,
+                                  make_body)
 from nagslang.resources import resources
 
 
@@ -12,6 +13,7 @@
 
     def __init__(self, space, name, shape, renderer):
         self._name = name
+        self.collected = False
         shape.sensor = True
         super(CollectibleGameObject, self).__init__(
             SingleShapePhysicser(space, shape),
@@ -23,9 +25,12 @@
 
     def _collect(self, protagonist):
         protagonist.add_item(self._name)
-        # TODO: Make this less hacky.
         self.physicser.remove_from_space()
-        self.renderer = render.NullRenderer()
+        self.collected = True
+
+    def update(self, dt):
+        if self.collected:
+            return Result(remove=[self])
 
 
 class Gun(CollectibleGameObject):
--- a/nagslang/enemies.py	Fri Sep 06 23:47:44 2013 +0200
+++ b/nagslang/enemies.py	Fri Sep 06 23:58:15 2013 +0200
@@ -9,7 +9,8 @@
 from nagslang.constants import (COLLISION_TYPE_ENEMY, COLLISION_TYPE_FURNITURE,
                                 ACID_SPEED, ACID_DAMAGE, ZORDER_MID)
 from nagslang.events import EnemyDeathEvent, FireEvent
-from nagslang.game_object import GameObject, SingleShapePhysicser, make_body
+from nagslang.game_object import (GameObject, SingleShapePhysicser, Result,
+                                  make_body)
 from nagslang.mutators import FLIP_H
 from nagslang.resources import resources
 from nagslang.utils import vec_with_length
@@ -68,9 +69,8 @@
 
     def lose_health(self, amount):
         self.health -= amount
-        if self.health < 0:
+        if self.health <= 0:
             self.physicser.remove_from_space()
-            self.remove = True
             EnemyDeathEvent.post(self.physicser.position, self.enemy_type)
 
     def set_direction(self, dx, dy):
@@ -125,6 +125,11 @@
         y_step = random.choice([-1, 0, 1])
         return x_step, y_step
 
+    def update(self, dt):
+        super(Enemy, self).update(dt)
+        if self.health <= 0:
+            return Result(remove=[self])
+
 
 class DeadEnemy(GameObject):
     def __init__(self, space, world, position, enemy_type='A'):
@@ -194,7 +199,7 @@
             self._switch_direction()
         self.set_direction(x_step, y_step)
         self.ranged_attack(300, ACID_SPEED, ACID_DAMAGE, 'acid', 0.2)
-        super(PatrollingAlien, self).update(dt)
+        return super(PatrollingAlien, self).update(dt)
 
     @classmethod
     def requires(cls):
@@ -250,7 +255,7 @@
         self.ranged_attack(300, ACID_SPEED, ACID_DAMAGE, 'acid', 0.2)
         dx, dy = self._calc_movement()
         self.set_direction(dx, dy)
-        super(ChargingAlien, self).update(dt)
+        return super(ChargingAlien, self).update(dt)
 
     @classmethod
     def requires(cls):
@@ -290,8 +295,8 @@
             return self.greedy_move(target)
 
     def update(self, dt):
-        super(RunAndGunAlien, self).update(dt)
         self.count += 1
+        return super(RunAndGunAlien, self).update(dt)
 
     @classmethod
     def requires(cls):
--- a/nagslang/game_object.py	Fri Sep 06 23:47:44 2013 +0200
+++ b/nagslang/game_object.py	Fri Sep 06 23:58:15 2013 +0200
@@ -15,6 +15,16 @@
 from nagslang.events import DoorEvent
 
 
+class Result(object):
+    '''
+    Return from an update() function, to add new objects to the world, and/or
+    remove old objects.
+    '''
+    def __init__(self, add=(), remove=()):
+        self.add = add
+        self.remove = remove
+
+
 def get_editable_game_objects():
     classes = []
     for cls_name, cls in globals().iteritems():
@@ -125,7 +135,6 @@
         self.interactible = interactible
         if interactible is not None:
             self.interactible.set_game_object(self)
-        self.remove = False  # If true, will be removed from drawables
         self._timers = {}
         self._active_timers = {}
 
@@ -482,8 +491,7 @@
             if hasattr(shape, 'physicser'):
                 shape.physicser.game_object.hit(self)
             self.physicser.remove_from_space()
-            self.remove = True
-            break
+            return Result(remove=[self])
 
 
 class ClawAttack(GameObject):
@@ -507,7 +515,7 @@
         super(ClawAttack, self).update(dt)
         if self.lifetime > 0.1:
             self.physicser.remove_from_space()
-            self.remove = True
+            return Result(remove=[self])
 
 
 class HostileTerrain(GameObject):
--- a/nagslang/screens/area.py	Fri Sep 06 23:47:44 2013 +0200
+++ b/nagslang/screens/area.py	Fri Sep 06 23:58:15 2013 +0200
@@ -243,9 +243,12 @@
         super(AreaScreen, self).tick(seconds)
         self.tick_protagonist()
         for drawable in self._drawables:
-            drawable.update(seconds)
-            if drawable.remove:
-                self._drawables.remove(drawable)
+            result = drawable.update(seconds)
+            if result is not None:
+                for new_drawable in result.add:
+                    self._drawables.add(new_drawable)
+                for old_drawable in result.remove:
+                    self._drawables.remove(old_drawable)
 
     def render_health_bar(self, surface, damage_experienced=None):
         bar_surface = pygame.Surface((110, 50)).convert(surface)