All I want to do is simple (?) 2D bounding-radius collision detection.
So far, what I have written works, but is slow with large numbers of intersecting objects... but it is as follows (written in python, by the way):
One master "Game" class, contains the list of "GameObject" objects in a variable called scene. Every object has a function called "Think" which is the function used to update position, do motion calculation, collision detection, and set up the next frame of animation if applicable. These are all called in a loop "for each object in game.scene".
In each object's Think() function, it searches for collisions in a loop that (once again) iterates "for each object in game.scene". It check to make sure it is not checking collision with itself, and then checks by what I call a "RadiusOverlap". This function is as follows:
Check for collisions between self, and objects in game.scene
def CollisionScan(self):
for obj in self.game.scene:
if obj != self and obj.collides and not obj.collisionScanned:
if self.collide:
if obj.type in self.collide:
obj.CheckCollision(self)
else:
obj.CheckCollision(self)
self.collisionScanned = True
Check for an overlap:
def CheckCollision(self, obj):
info = self.RadiusOverlap(obj)
if info[0] <= 0:
self.Collide(obj, info)
(Collide() simply stores the collision information in a list)
Support functions:
def RadiusOverlap(self, obj):
return [self.DistanceTo(obj) - obj.asset.radius - self.asset.radius, self.AngleToO(obj)]
RadiusOverlap() returns the distance between to objects taking into account bounding circles. If the first item in the return list is negative, there is an intersection.
And the relevant support functions:
def DistanceTo(self, obj):
return math.sqrt((obj.x - self.x)**2 + (obj.y - self.y)**2)
def AngleToO(self, obj):
return self.AngleToP(obj.x, obj.y)
def AngleToP(self, x, y):
return math.atan2(x - self.x, y - self.y)%(math.pi*2)
(by the way, the ** operator is an exponent). RadiusOverlap returns the distance between objects taking into account radius, and also returns the angle to the object (for motion collision repsonse stuff that's not implemented yet). Currently, if two objects are found to intersect, the object, overlap, and angle is stored in a list for later processing. In the Think function, each item in the collision list is iterated through, each object is moved apart by the RadiusOverlap as stored previously.
My problem is that this setup is very s-l-o-w. Is that obvious to anyone? How can I make it better??
Thanks.