GP32 How to code collisions


In the old days, the simplest was to make your sprites fill as much of their
space as possible... e.g. if your sprites are 32x32, make them fill as much of
that 32x32 square as possible. Then, you only have to check if the 32x32 square
areas overlap. That's why quite a few games from the eighties used very
"squarish" sprites. It works well for some, top-down car games, etc.

Sometimes, people use an algorithm that divides their sprite up into smaller squares, and checks the overlap of each smaller square with the other object.
It can get a bit unwieldy with animated sprites though.

After that, there are more complex ways, that actually check for an overlap
at the pixel level. That would be done at the drawing of the sprite itself, depending
on how the sprite is being drawn (manually using transparency masks, etc).
Anyone remember Jetset Willy?

It's a long time since I did any of that kind of thing, I'm sure there are other
good ways...?

Cheers,
Martin.
 
Hi

If you wait a few weeks the first version of Blazer will be ready - this has a full 2d collision engine built in. In Blazer I've used 2d Line,Circle,Ellipse and Rectangle collision along with a modified verlett integrator - and it works a treat - stuff like sonic/mario are extremely easy to knock up within a few mins work. Keep watching
 
Thanks animal it's just the answer i wanted.

To ZardozJones: Can you advance something about what algoritmes are you using? No code necessary, only theory. Thanks


Another question.

What is the best formula to compara byte colisions?

Imagine you have to bytes of two diferent sprites s1 an s2. And you have the transparent color of each (c1 and c2).

perhaps !(s1 && c1) || !(s2 && c2) ?
 
Here's a collision routine I wrote, it gives pixel perfect collision and it's reasonably fast. Feel free to use it if it helps.
It takes the same parameters as GpTransBlt so it's nice and easy to use.

Dave

int images_collide(int dx1, int dy1, int dw1, int dh1, uchar * src1, int sx1, int sy1, int sw1, int sh1, int c1, int dx2, int dy2, int dw2, int dh2, uchar * src2, int sx2, int sy2, int sw2, int sh2, int c2)
{
int close;
close=0;
int cl,cr,ct,cb,cx,cy,ofx1,ofx2,ofy1,ofy2;

//**** Check to see whether the 2 gfx are even close - no point pixel checking if not ****

if ((dx1 >= dx2-dw1) && (dx1 <= dx2+dw2) && (dy1 >= dy2-dh1) && (dy1 <= dy2+dh2)) close=1;
// if ((dx2 >= dx1-dw2) && (dx2 <= dx1+dw1) && (dy2 >= dy1-dh2) && (dy2 <= dy1+dh1)) close=1;

if (close==0) return (close);


//**** Work out total region that may have a collision within ****
cl=dx1;
if (dx2 < dx1) cl=dx2;
cr=dx1+dw1;
if (dx2+dw2 > dx1+dw1) cr=dx2+dw2;
ct=dy1;
if (dy2 < dy1) ct=dy2;
cb=dy1+dh1;
if (dy2+dh2 > dy1+dh1) cb=dy2+dh2;


//**** Go through the collision region and see if both gfx have an unmasked pixel ****
for (cx=cl;cx<=cr;cx++)
for (cy=ct;cy<=cb;cy++)
{
if ((cx>dx1) && (cx<=dx1+dw1) && (cy>dy1) && (cy<=dy1+dh1))
{
if (*(src1+((cx-dx1)+sx1-1)*sh1+sh1-((cy-dy1)+sy1)) != c1)
{
if ((cx>dx2) && (cx<=dx2+dw2) && (cy>dy2) && (cy<=dy2+dh2))
{
if (*(src2+((cx-dx2)+sx2-1)*sh2+sh2-((cy-dy2)+sy2)) != c2) return (1);
}
}
}

}

//**** If we've got here then no collision detected so return zero ****
return(0);
}
 
There is a SDL collision detection library on www.libsdl.org site. It involves a bitmask method. Wich can even return the area of collision. There is documentation explaining how it works and how it could be improved.

I wanted to try to port it but I'm working with simpler stuff right now.
 
Back
Top