Game Programming and Development Tools

Collision detection. – Lazarus

Lazarus

Member

Posts: 1668
From: USA
Registered: 06-06-2006
Hey guys.

I'm working on a program with a two dimensional maze.(GLBasic, btw)
The background is a single image with blue lines marking out where the walls are.

Now I have the keyboard controlled sprite - another image.
My problem is trying to detect collisions between the sprite and the blue parts of the maze.

Any ideas?

(Yeah - GLBasic's built-in collision commands don't seem to be much use here - the two of them that there are.)

dartsman

Member

Posts: 484
From: Queensland, Australia
Registered: 03-16-2006
well as long as you can get access to the raw image data in your background and the sprite you'll be set to do per-pixel collision detection.

Now, best thing would be to make sure that the background image and the sprite are able to match up (as in if the background image is 800x600 that you don't stretch it to say 1024x768 or down to 400x300 (unless your willing to put in scaling code as well)).

You'll have your offset for your sprite in screen coords, so all you need to do is check your sprite to the background image offset so that you only check sprite.width X sprite.height on both the sprite and the background image. I hope I'm explaining it well enough...

Some pseudo/c++ code:

struct Image
{
byte *data; // unsigned char, holds the image data itself, this is for 256 colours... change to fit colour range..
int width; // width of the image
int height; // height of the image
int posX; // the position X on the screen where this image is drawn to
int posY; // the position Y on the screen where this image is drawn to

void Load(char *filepath); // now I won't write out this code :P but it would load up the file (.bmp) putting the raw colour data into the variable 'data'
};

/* we use the following colour keys to determine if there was a collision:
Sprite.data[offset] Background.data[offset] Outcome
Colour: 0 0 No Collision
1 0 No Collision
0 1 No Collision
1 1 Collision
As 0 would represent a 'invisible' part of the image.. and 1 is solid (not invisible, so would have to be rendered.
*/
const byte SPRITE_COLOUR_KEY = 0; // the colour which is our 'invisible' sprite colour
const byte BACKGROUND_COLOUR_KEY = 0; // the colour which is our 'invisible' background colour

Image Sprite;
Sprite.Load("sprite.bmp");
Image Background;
Background.Load("background.bmp");

bool PerPixelCollisionCheck()
{
int offsetX = Sprite.posX;
int offsetY = Sprite.posY;

for (int y = 0; y < Sprite.height && y < Background.height; ++y)
{
for (int x = 0; x < Sprite.width && x < Background.width; ++x)
{
int spriteOffset = x + (y * Sprite.width);

// not too sure about this offset calculation, don't have too much time to check, *seems* to be right..
int backgroundOffset = (x + offsetX) + ((y + offsetY) * Background.height)));

if (Sprite.data[spriteOffset] != SPRITE_COLOUR_KEY &&
Background.data[backgroundOffset] != BACKGROUND_COLOUR_KEY)
{
// presume collision
// you should update this check to accommodate for more flexibility such as specific colour checks rather then just 'invisible' checks
return true;
}
}
}

return false;
}

I don't know if that is like 'standard practice' for per-pixel collision detection, but it *should* would. I haven't compiled it or anything, so there could be some mistakes.

So I hope that helped... I know it's not in GLBasic, but hopefully it'll guide you in the right way

------------------
www.auran.com

Lazarus

Member

Posts: 1668
From: USA
Registered: 06-06-2006
Well, I'll try it out. Thanks Dart.
dartsman

Member

Posts: 484
From: Queensland, Australia
Registered: 03-16-2006
No problem... just let me know how it goes, or if you need more explained... The pain will be the collision response, unless you just use the old position if the new position isn't good.

------------------
www.auran.com

Lazarus

Member

Posts: 1668
From: USA
Registered: 06-06-2006
I've tried several different ways(including per-pixel collision detection - thanks again for your example, Dart) - still problems.

Either GLBasic has a bug in its collision detection functions or I'm really messing up somewhere. Or both. Anyway, I'm asking on the forum about it.

Oh - with collision response, I just use the old position if the new one is invalid.

dartsman

Member

Posts: 484
From: Queensland, Australia
Registered: 03-16-2006
What problems are you having?

Have you looked into basic bounding box collision detection?

------------------
www.auran.com

Lazarus

Member

Posts: 1668
From: USA
Registered: 06-06-2006
Well I'll be...

I figured out the problem - just a simple if/then bug. *slaps forehead*

Well, thanks Dart. I think I'll go with bounding box collision detection - it seems to work best.

dartsman

Member

Posts: 484
From: Queensland, Australia
Registered: 03-16-2006
yep, sounds good

------------------
www.auran.com