ID:271081
 
I've been trying to setup circular collision detection for my game, but no luck.

This is what I had in mind when setting it up, but as you can see, no luck. :(

    proc/Collisions(Dir)

// collision detection setup;
var/list/collisions = new
var/turf/collisionTurf = get_step(src,Dir)

// collision detection turf contents;
var/dx = abs(x - collisionTurf.x)
var/dy = abs(y - collisionTurf.y)
var/circle = sqrt(dx*dx + dy*dy)

// collision detection turf;
if(circle < (radius + collisionTurf.radius))
collisions += collisionTurf

// collision detection contents;
var/atom/collision

// collision detection loop;
for(collision in collisionTurf.contents)

// collision detection item;
dx = abs(x - collisionTurf.x)
dy = abs(y - collisionTurf.y)
circle = sqrt(dx*dx + dy*dy)

// bump check;
if(circle < (radius + collision.radius))
world<<"c"
collisions += collision

// return results;
return collisions


The formula for detection is

(abs(x-c.x))2+(abs(y-c.y))2

And to detect if there are collisions in a certain spot I do

        // collision detection contents;
var/list/collisions = Collisions(Dir)

// collision detection check;
if(collisions && collisions.len)
return


Ideas?
If you just want to check for collisions between two circles, you just have to compare the distance between the circle's centres and the sum of the two circle's radius's. Therefore, you can create a simple distance function, and compare.

proc/distance(atom/A, atom/B)
return sqrt((A.x-B.x)*(A.x-B.x) + (A.y-B.y)*(A.y-B.y))

...

if(distance(A, B) < (A.radius + B.radius))
// collision has occurred
In response to Unknown Person
Unknown Person wrote:
If you just want to check for collisions between two circles, you just have to compare the distance between the circle's centres and the sum of the two circle's radius's. Therefore, you can create a simple distance function, and compare.

> proc/distance(atom/A, atom/B)
> return sqrt((A.x-B.x)*(A.x-B.x) + (A.y-B.y)*(A.y-B.y))
>
> ...
>
> if(distance(A, B) < (A.radius + B.radius))
> // collision has occurred
>


finding the square root if a number is a costly operation, and unless you really need the actual distance then you shouldn't take the square root. for a comparison, you can compare the square of the distance to the square of the sum of the radii. since you'd have to calculate the square of the distance to get the actual distance, you save yourself from computing a square root by computing (A.radius + B.radius) * (A.radius + B.radius) instead.
In response to OneFishDown
OneFishDown wrote:
finding the square root if a number is a costly operation, and unless you really need the actual distance then you shouldn't take the square root. for a comparison, you can compare the square of the distance to the square of the sum of the radii. since you'd have to calculate the square of the distance to get the actual distance, you save yourself from computing a square root by computing (A.radius + B.radius) * (A.radius + B.radius) instead.

This is a nice tip, I'll be keeping this in mind.