• Announcements

Archived

This topic is now archived and is closed to further replies.

Collision Detection with different shapes

Recommended Posts

BeerNutts    4400
OK, I have a 2D side-scrolling space shooter, and I have many different object shapes, and this is how I currently detect collisions: If the ratio of the object''s (a .bmp basically) X/Y is between certain values, let it be described by a bounding circle. If it is too rectangular, let it use a bounding rectangle. Now, it''s easy enough to see if a circle and a circle have collided, or if a sqaure and a square collided, but seeing if a circle and a square collided took a bit more programming. My current solution is checking 8 different positions on the circle and the rectangle, and seeing if they are within range, but if someone has a better solution, please tell me. However, what I really want is some way to actually look at the bitmap, and tell where the object really starts (ie, don''t include the alpha value (black) in the defintion of the object). Is there an easy way to do this? What has been the best way in the past? All help is appreciated. Thanks, Will

Share on other sites
Guest Anonymous Poster
1. From what you''ve said, I don''t understand how you can recieve any benefit from using bounding circles instead of bounding rectangles.

2. You can detect the collision of a bounding circle and a bounding rectangle like this:

struct {
double x, y; //upper left corner of rectangle
double w, h; // width & height of rectangle
} rect;
stuct {
double x, y; //center of circle
} circ;
//checking bounding box
if (circ.x+r < rect.x) return false;
if (circ.x-r >= rect.x + rect.w) return false;
if (circ.y+r < rect.y) return false;
if (circ.y-r >= rect.y + rect.h) return false;
/*bounding boxes collide; but there are 4 possible regions that would cause this but not involve a collision*/
double rsqr = circ.r * circ.r;
//now check upper left corner for a false positive
if ((circ.x < rect.x) && (circ.y < rect.y)) {
double dx = circ.x - rect.x;
double dy = circ.y - rect.y;
if (dx*dx+dy*dy > rsqr) return false;
}
//now check upper right corner for a false positive
if ((circ.x > rect.x + rect.w) && (circ.y < rect.y)) {
double dx = circ.x - (rect.x + rect.w);
double dy = circ.y - rect.y;
if (dx*dx+dy*dy > rsqr) return false;
}
//now check lower left corner for a false positive
if ((circ.x < rect.x) && (circ.y < rect.y + rect.h)) {
double dx = circ.x - rect.x;
double dy = circ.y - (rect.y + rect.h);
if (dx*dx+dy*dy > rsqr) return false;
}
//now check lower right corner for a false positive
if ((circ.x > rect.x + rect.w) && (circ.y < rect.y + rect.h)) {
double dx = circ.x - (rect.x + rect.w);
double dy = circ.y - (rect.y + rect.h);
if (dx*dx+dy*dy > rsqr) return false;
}
//all cases handled; must be colliding
return true;

3. In my game, I use pixel-perfect collisions; when a bitmap is loaded, I create a bitmask which has 1 bit per pixel in the image, which is then shifted and anded to detect two sprites claiming the same pixel.

Share on other sites
BeerNutts    4400
Anony, It looks like your algorithm will work (so simple, why didn''t I think of that? , but your 1st and last statements intrigue me.
1: Imagine the following situation: I have a spaceship bitmap which is pretty long X-wise, and short Y-wise. Now, imagine a large asteroid (basically a circle, where X and Y are about equal) coming at the spaceship. If I were to use a bounding rectangle for the asteroid, then the corners of the asteroid bitmap, where there is only my alpha value, could easyily hit the spaceship, but it looks like the steroid wasn''t near the spaceship.

2: In your bit mask you create, do you somehow scan the bitmap, and only mark the places where there is a color other than the alpha value? That is what I''m really looking for. If I could somehow scan the bitmap, and create a bitmask for each bitmap where the bits are set only where there is color, then I would be set. Any suggestions?

Thanks