Archived

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

Collision Detection with different shapes

This topic is 6005 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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 this post


Link to post
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
double r; //radius 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 this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
I''d recommend you to use per-pixel collission really.. bounding box is faster, but as long as your objects aren''t too big it shouldn''t matter that much. The collission detection system I use (for my own tiny little sort-of game project) works by checking if two tiles overlap eachother, and then just check if the color''s above 0 for both at a given point in that area. Of course, with 16x16 size 256-color raw-data tiles that''s pretty easilly done.. though I''d imagine it wouldn''t be too hard to check through the memory where you store loaded images and try to make a mask where there''s solid pixels.

Of course, you could make mask images outside the engine itself too, and save them in seperate files. I know some games have been utilizing premade masks..

"Goodness reflects the light; and evil, bears the seed of all darkness. These are the mirrors of the soul, the reflections of the mind. -Choose well..." (Unknown)

Share this post


Link to post
Share on other sites