gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Coding > sprite collision detection

#1754 - strider999 - Wed Jan 22, 2003 4:31 pm

whats the best way to do this? im planning on doing a super mario type game, but im new to the whole console programming scene. any tips?

#1759 - SamX - Wed Jan 22, 2003 5:16 pm

I am very much a newbie... But if you're going to have your sprite it'll be at x,y.

say your player struct has x and y and you give the sprite its x,y from player.x and player.y (same with enemy sprites enemy[0].x or whatever) then just use a bounding-box around the player and enemy (worked out from player.x, player.x + player.width, player.y, player.y + player.height.

Now with the bounding box you check that the boxes around the player and enemy haven't slipped on top of each other....

Sorry I'm not much help... You probably knew all this, but I felt like trying to offer something from my useless self ;) Give it a min and someone else will say something better.
_________________
-Sam

[Images not permitted - Click here to view it] [Images not permitted - Click here to view it]

#1764 - Splam - Wed Jan 22, 2003 6:30 pm

Bounding boxes are one way to do it but due to the processing time involved (you could be checking 50 bullets against 20 enemies etc) I tend to use a coarse collision 1st ie in your player/bullet/enemy structures keep a value (whatever size is up to you) that is calculated by the x and y divided by your "coarse" value, so maybe 8x8 , your collision value would be something like y/8 x/8 and put those into a variable like u16 = (coarsey<<8) | coarsex then you only need to check that value against other sprites coarse values, if they match then they're somewhere on the same 8x8 screen block. You can make this as coarse as you want (8x8 16x16 etc) then either use it alone or add bounding box collision as well if needed for finer detection.

#1835 - princew - Fri Jan 24, 2003 3:12 am

That way seems cool. I never thought of a grid test first, then possibly testing sprites within the grid.

Here's a method I came up with and it seems to work fast enough. I used it in my asteroids game where there are potentially 50 asteroids on the screen with up to 5 bullets, an enemy, and a player all collision detecting running at 60fps and no slowdown...

bool TestCollision( SpriteType* Sprite1, SpriteType* Sprite2 ) {
if ( (Sprite1->x + Sprite1->BoxX2) < (Sprite2->x + Sprite2->BoxX1) ) {
return false;
} else if ( (Sprite1->x + Sprite1->BoxX1) > (Sprite2->x + Sprite2->BoxX2) ) {
return false;
} else if ( (Sprite1->y + Sprite1->BoxY2) < (Sprite2->y + Sprite2->BoxY1) ) {
return false;
} else if ( (Sprite1->y + Sprite1->BoxY1) > (Sprite2->y + Sprite2->BoxY2) ) {
return false;
}

return TRUE; // sprites collided
}

Basically all it does is test each side of the bounding boxes one at a time and returns as soon any one of them fails. This means that the majority of the sprites being tested will return false after only 1 or 2 tests. As I said, I've used this and tested quite a few sprites onscreen at once without slowdown. Furthermore you will want to make sure you only bother testing against sprites that are visible or active.

Russ


Last edited by princew on Fri Jan 31, 2003 6:58 pm; edited 1 time in total

#1853 - Splam - Fri Jan 24, 2003 3:53 pm

Yeah, bounding box detections can be fast and certainly something like asteroids where it's a 1 collisions 1 reaction detection. My method is only really needed when collisions against multiple objects is needed.

#2261 - maniac - Fri Jan 31, 2003 10:28 pm

Yet another way to do a quite fast collision detection is to precalculate the outer bounds of the sprites, (ie xstart and xend for each row on the sprites where xstart is the first pixel != transparent color and xend should be straight forward). Then it's just a simple comparison to get a true pixel collision detection!

On the other hand this technique will require quite a bit of overhead (cause of all the precalculated values). So this particular technique is an speed vs. overhead issue. But it works very good!