Hello,
I’ve been experimenting with circle vs. circle collisons. Ive been using the code below to check for collisions and seperate the objects.
It works just fine, except in conditions where more than two circles are touching at the same time. For example, if three circles or more are colliding at the same time, they can sometimes overlap and then struggle to separate.
I think I know why this is happening. The code loops through the object array and checks for a collision between each object one at a time and alters their positions and velocities. The problem is that if it finds a collision between objects at the end of the array, the positions of the objects could be changed in such a way that they cause an overlap with an object that was checked earlier, for which no collision was detected. This new collision then goes undetected and this flaw is amplified when the loop runs again.
Does anyone know if there is a simple solution to this problem (maybe a recursive one?) or should I be looking a more robust grid based collision detection system?
Here’s the code I’m experimenting with if anyone is interested in this problem
Thanks!
function circleCollision(circleOne:MovieClip, circleTwo:MovieClip):void
{
//Find radius, x and y positions of circleOne
var circleOne_Radius = circleOne.width/2;
var circleOne_X = circleOne.x;
var circleOne_Y = circleOne.y;
//Find radius, x and y positions of circleTwo
var circleTwo_Radius = circleTwo.width/2;
var circleTwo_X = circleTwo.x;
var circleTwo_Y = circleTwo.y;
//Calculate the radii of both circles combined
var totalRadii = circleOne_Radius + circleTwo_Radius;
//Find the distances between the object on the xnd y axis
var dx:Number = circleOne_X - circleTwo_X;
var dy:Number = circleOne_Y - circleTwo_Y;
var distance:Number = Math.sqrt(dx * dx + dy * dy);
//Check wether objects are colliding
if(distance < totalRadii)
{
//Find the amount of overlap between circles
var overlap = totalRadii - distance;
//Calculate normals
var normalX:Number = dx / distance;
var normalY:Number = dy / distance;
//Find the direction vector and use it to calculate the new velocities
var directionVector:Number = ((circleOne.vx - circleTwo.vx) * normalX) + ((circleOne.vy - circleTwo.vy) * normalY);
var newVx:Number = directionVector * normalX;
var newVy:Number = directionVector * normalY;
//Move circleOne out of the collision
circleOne.x += normalX * overlap;
circleOne.y += normalY * overlap;
//Apply new velocites to objects
circleOne.vx -= newVx;
circleOne.vy -= newVy;
circleTwo.vx += newVx;
circleTwo.vy += newVy;
}
}
The objects are stored in an array called _thingsInTheGame. This is the loop that runs in an ENTER_FRAME event.
function onEnterFrame(event:Event):void
{
for (var i = 0; i < _thingsInTheGame.length - 1; i++)
{
var objectA:MovieClip = _thingsInTheGame*;
for (var j = i + 1; j < _thingsInTheGame.length; j++)
{
var objectB:MovieClip = _thingsInTheGame[j];
//Check for collision
circleCollision(objectA,objectB);
}
}
}