Bullet.step: Need to re-check finished in a second action iteration in case an action...
[python-bulletml.git] / bulletml / impl.py
index dad5601..0c40f1e 100644 (file)
@@ -4,8 +4,6 @@ from __future__ import division
 
 from math import atan2, sin, cos
 
-from bulletml.parser import ActionDef, ActionRef
-
 __all__ = ["Action", "Bullet"]
 
 class Action(object):
@@ -48,10 +46,6 @@ class Action(object):
         return "%s(pc=%r, actions=%r)" % (
             type(self).__name__, self.pc, self.actions)
 
-    def Child(self, action, params, rank, repeat=1):
-        actions, params = action(params, rank)
-        return type(self)(self, actions, params, rank, repeat)
-
     def vanish(self):
         """End this action and its parents."""
         if self.parent:
@@ -80,8 +74,8 @@ class Action(object):
             owner.speed += self.speed
 
         if self.direction_frames > 0:
-            # I'm still not sure what the aim check is supposed to do.
             self.direction_frames -= 1
+            # I'm still not sure what the aim check is supposed to do.
             if self.aiming and self.direction_frames <= 0:
                 owner.direction += owner.aim
             else:
@@ -120,13 +114,7 @@ class Action(object):
                     self.pc = 0
                     action = self.actions[self.pc]
 
-            if isinstance(action, (ActionDef, ActionRef)):
-                child = self.Child(action, s_params, rank)
-                owner.replace(self, child)
-                child.step(owner, created)
-                break
-
-            elif action(owner, self, s_params, rank, created):
+            if action(owner, self, s_params, rank, created):
                 break
 
 class Bullet(object):
@@ -143,9 +131,11 @@ class Bullet(object):
     rank - game difficulty, 0 to 1, default 0.5
     tags - string tags set by the running actions
     appearance - string used to set bullet appearance
+    radius - radius for collision
+    finished - true if all actions are finished and the bullet vanished
 
     Contructor Arguments:
-    x, y, direction, speed, target, rank, tags, appearance
+    x, y, direction, speed, target, rank, tags, appearance, radius
         - same as the above attributes
     actions - internal action list
     Action - custom Action constructor
@@ -154,33 +144,34 @@ class Bullet(object):
 
     def __init__(self, x=0, y=0, direction=0, speed=0, target=None,
                  actions=(), rank=0.5, tags=(), appearance=None,
-                 Action=Action):
+                 radius=0.5):
         self.x = self.px = x
         self.y = self.py = y
+        self.radius = radius
         self.mx = 0
         self.my = 0
         self.direction = direction
         self.speed = speed
         self.vanished = False
+        self.finished = False
         self.target = target
         self.rank = rank
         self.tags = set(tags)
         self.appearance = appearance
-        # New bullets reset the parent hierarchy.
-        self.actions = [Action(None, action, params, rank)
-                         for action, params in actions]
+        self.actions = list(actions)
 
     @classmethod
     def FromDocument(cls, doc, x=0, y=0, direction=0, speed=0, target=None,
                      params=(), rank=0.5, Action=Action):
         """Construct a new Bullet from a loaded BulletML document."""
-        actions = [a(params, rank) for a in doc.actions]
+        actions = [action(None, Action, params, rank)
+                   for action in doc.actions]
         return cls(x=x, y=y, direction=direction, speed=speed,
-                   target=target, actions=actions, rank=rank, Action=Action)
+                   target=target, actions=actions, rank=rank)
 
     def __repr__(self):
         return ("%s(%r, %r, accel=%r, direction=%r, speed=%r, "
-                "actions=%r, target=%r, appearance=vanished=%r)") % (
+                "actions=%r, target=%r, appearance=%r, vanished=%r)") % (
             type(self).__name__, self.x, self.y, (self.mx, self.my),
             self.direction, self.speed, self.actions, self.target,
             self.appearance, self.vanished)
@@ -199,24 +190,6 @@ class Bullet(object):
         else:
             return atan2(target_x - self.x, target_y - self.y)
 
-    @property
-    def finished(self):
-        """Check if this bullet is finished running.
-
-        A bullet is finished when it has vanished, and all its
-        actions have finished.
-
-        If this is true, the bullet should be removed from the screen.
-        (You will probably want to cull it under other circumstances
-        as well).
-        """
-        if not self.vanished:
-            return False
-        for action in self.actions:
-            if not action.finished:
-                return False
-        return True
-
     def vanish(self):
         """Vanish this bullet and stop all actions."""
         self.vanished = True
@@ -246,8 +219,14 @@ class Bullet(object):
         """
         created = []
 
+        finished = self.vanished
         for action in self.actions:
             action.step(self, created)
+            finished = finished and action.finished
+        if finished:
+            for action in self.actions:
+                finished = finished and action.finished
+        self.finished = finished
 
         speed = self.speed
         direction = self.direction