X-Git-Url: https://git.yukkurigames.com/?p=python-bulletml.git;a=blobdiff_plain;f=bulletml%2Fcollision.py;h=2e88b3c0a492008a8c62cb0a23c0c92fbd9f3f4f;hp=1683e58f6ca70fa583e65e9e967835d2c6831472;hb=HEAD;hpb=ee9429c2c319d5d794e49da7b0fe13fca9945194 diff --git a/bulletml/collision.py b/bulletml/collision.py index 1683e58..2e88b3c 100644 --- a/bulletml/collision.py +++ b/bulletml/collision.py @@ -1,7 +1,7 @@ """Simple collision check. This module provides simple collision checking appropriate for -shmups. It provides a routine to check whether two moving circles +shmups. It provides routines to check whether two moving circles collided during the past frame. An equivalent C-based version will be used automatically if it was @@ -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)