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 > Not sure about this...

#9319 - VgSlag - Fri Aug 01, 2003 2:10 pm

I've posted something in beginners forum but am not sure if it's better suited to this one?

I don't want to start cross-posting but maybe there are more people that can help in this one?

If you could take a look here it would be much appreciated.

Sorry if this is considered a cross post, feel free to delete it!

Thanks,

G

#9321 - Nessie - Fri Aug 01, 2003 4:11 pm

Hmm, perhaps a bit too early in the morning to risk thinking about something, but...heh..

Anyway, if you are using signed fixed 16:16 (s32), I'd think that using distanceSquared would overflow the datatype so fast, I'd be surprised it would ever work? It should be easy enough to check whether this is part of your problem or not...

So...howz about this assuming your shot is just a pixel:
Code:
s32 distX, distY, distSquared;

distX = bulletX - asteroidX;  // get x, y difference with our fixed point values
distY = bulletY - asteroidY;

distX >>= 16; // convert from fixed
distY >>= 16;

distSquared = distX * distX + distY * distY;

if ( distSquared <= ASTEROID_RADIUS_SQUARED )
{
    // Collision!
}

Note that ASTEROID_RADIUS_SQUARED is not a fixed point value..and if your shot is something larger than a pixel, like a roundish sprite or something, you can slightly improve the accuracy of the check by something like this:
Code:
if ( distSquared <= (ASTEROID_RADIUS_SQUARED + SHOT_RADIUS_SQUARED))

#9322 - VgSlag - Fri Aug 01, 2003 4:37 pm

I'm only checking against a single pixel for the shot as it's small enough not to worry.

What you suggested has worked but I was trying to avoid doing any math on floats as I'm going to need to check up to 4 bullets on upto 4 asteroids per frame.

Any idea how I could stop them overflowing?

Thanks for the help btw

#9327 - tepples - Fri Aug 01, 2003 6:24 pm

Try shifting the value to the right 8 bits (making it 24.8) before squaring it. Then when you multiply two 24.8s, you get a 16.16.

There's still a chance of overflow if the radius is large enough, so check the bounding square before you check the bounding circle.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#9341 - Nessie - Sat Aug 02, 2003 1:35 am

Actually not--there is no usage of floats anywhere in the math I proposed. Anyway, if you are worried about speed and aren't into ASM, another solution which may or may not be faster (depending on how fast abs() is and whether the typical bullet will slip past the below test but still fail the full test) could be as simple as a quick early out:
Code:
if ( abs(bulletX - asteroidX) <= ASTEROID_RADIUS_FIXED )
{
    // Potential collision!  Do more conclusive testing to make sure
    //  ..as in, maybe do the full blown distance squared check
}
...I'm sure there are plenty of other ways to do a rough first cut to rule out most of the asteroids.

#9350 - VgSlag - Sat Aug 02, 2003 2:26 pm

Cheers Nessie,

I've stuck with your first answer, it's really fast, when checking 5 asteroids against all the bullets it's still greased fast.

Thanks for your help you two, I'll put the file up here when it's finished if you wanna play it.

G