Give bullets a radius by default. Use try/except rather than getattr during collision...
authorJoe Wreschnig <joe.wreschnig@gmail.com>
Sat, 24 Apr 2010 08:23:48 +0000 (01:23 -0700)
committerJoe Wreschnig <joe.wreschnig@gmail.com>
Sat, 24 Apr 2010 08:23:48 +0000 (01:23 -0700)
bulletml/bulletyaml.py
bulletml/collision.py
bulletml/impl.py

index 2503c9d..2ec2f08 100644 (file)
@@ -30,7 +30,7 @@ def register(Loader=None, Dumper=None):
                 parser.Repeat, parser.Accel, parser.BulletDef,
                 parser.BulletRef, parser.ActionDef, parser.ActionRef,
                 parser.FireDef, parser.FireRef, parser.Offset,
-                parser.BulletML]:
+                parser.Appearance, parser.If, parser.BulletML]:
 
         def add(cls, loader, dumper):
             """Register a class in a new variable scope."""
index 1683e58..8aa17d3 100644 (file)
@@ -30,7 +30,10 @@ def overlaps(a, b):
 
     dx = a.x - b.x
     dy = a.y - b.y
-    radius = getattr(a, 'radius', 0.5) + getattr(b, 'radius', 0.5)
+    try:
+        radius = a.radius + b.radius
+    except AttributeError:
+        radius = getattr(a, 'radius', 0.5) + getattr(b, 'radius', 0.5)
 
     return dx * dx + dy * dy <= radius * radius
 
@@ -53,27 +56,32 @@ def collides(a, b):
     yb = b.y
 
     # Treat b as a point, we only need one radius.
-    radius = getattr(a, 'radius', 0.5) + getattr(b, 'radius', 0.5)
+    try:
+        radius = a.radius + b.radius
+    except AttributeError:
+        radius = getattr(a, 'radius', 0.5) + getattr(b, 'radius', 0.5)
 
     # Previous frame locations.
-    pxa = getattr(a, 'px', xa)
-    pya = getattr(a, 'py', ya)
-    pxb = getattr(b, 'px', xb)
-    pyb = getattr(b, 'py', yb)
+    try: pxa = a.px
+    except KeyError: pxa = xa
+    try: pya = a.py
+    except KeyError: pya = ya
+    try: pxb = b.px
+    except KeyError: pxb = xb
+    try: pyb = b.py
+    except KeyError: pyb = yb
 
     # Translate b's final position to be relative to a's start.
     # And now, circle/line collision.
     dir_x = pxa + (xb - xa) - pxb
     dir_y = pya + (yb - ya) - pyb
 
-    if abs(dir_x) < 0.0001 and abs(dir_y) < 0.0001:
-        # b did not move relative to a, so do point/circle.
-        dx = pxb - pxa
-        dy = pyb - pya
-        return dx * dx + dy * dy < radius * radius
-
     diff_x = pxa - pxb
     diff_y = pya - pyb
+    if (dir_x < 0.0001 and dir_x > -0.0001
+        and dir_y < 0.0001 and dir_y > -0.0001):
+        # b did not move relative to a, so do point/circle.
+        return diff_x * diff_x + diff_y * diff_y < radius * radius
 
     # dot(diff, dir) / dot(dir, dir)
     t = (diff_x * dir_x + diff_y * dir_y) / (dir_x * dir_x + dir_y * dir_y)
index f7edd5a..4785ef2 100644 (file)
@@ -131,9 +131,10 @@ 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
 
     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
@@ -141,9 +142,11 @@ class Bullet(object):
     """
 
     def __init__(self, x=0, y=0, direction=0, speed=0, target=None,
-                 actions=(), rank=0.5, tags=(), appearance=None):
+                 actions=(), rank=0.5, tags=(), appearance=None,
+                 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