Pixel Perfect Sprite Collisions

I am new to this list, so hello to everyone. I am quite inexpeienced with regards to c++ programming, so please bear with me, and if you have any suggestions or advice please don’t hesitate to let me know.

I am having a problem, in that I don’t know how to achieve pixel perfect sprite collisions. I have irregular shape images stored as bmp files with a background colour, which is set at Alpha using the RGB values and the relevent SDL function. The sprite system I am using is from the cone3d tutorials, located at http://cone3d.gamedev.net/cgi-bin/index.pl?page=tutorials/gfxsdl/tut3 . I think I understand the code I am using, so in that respect I am OK. The .bmp sprite frames are loaded into an array an of sdl surfaces and accessed through references to the struct they are stored in. There is a class for the sprite base, which holds the frames of the images and their associated times to pause between frames. There is also a class for each sprite, holding various data.

I have read examples of other sprite collisions using pixel perfect detection, and I understand that they access the pixel data of the overlap of the image RECTs and loop through every pixel in the overlapping rectangle, comparing pixel data each time to check for 2 non-alpha pixels. I do not know how to access the pixel data of the image files, or in this case I suppose it would be the relevent surface. I do not know how to tell whether the pixel being accessed has the same RGB values as the alpha channel for that surface.

I hope I have made myself clear, please feel free to email me privately if you have any questions.

Can anyone help me? Would I be better of using opengl for this, or is it unneccesary? The style of game I am making is a third-person 1v1 combat game, similar to mortal kombat. Thanks in advance for any help, advice, links, or code examples you show me.

Regards,
James

Hello James,

not that it’s well documented, but I did per-pixel detection in an SDL
asteroids game. It shows how to acces pixels etc.:

http://www.libsdl.org/games.php?order=name&category=any&completed=0&os=any&match_name=asteroids&perpage=50

Good luck,
Patrick.

On Mon, 24 Mar 2003 11:51:54 -0000 “James Pickard”
wrote.
I am new to this list, so hello to everyone. I am quite inexpeienced with

regards to c programming, so please bear with me, and if you have any

suggestions or advice please don’t hesitate to let me know.

I am having a problem, in that I don’t know how to achieve pixel perfect

sprite collisions. I have irregular shape images stored as bmp files with a

background colour, which is set at Alpha using the RGB values and the

relevent SDL function. The sprite system I am using is from the cone3d

tutorials, located at

http://cone3d.gamedev.net/cgi-bin/index.pl?page=tutorials/gfxsdl/tut3 . I

think I understand the code I am using, so in that respect I am OK. The
.bmp

sprite frames are loaded into an array an of sdl surfaces and accessed

through references to the struct they are stored in. There is a class for

the sprite base, which holds the frames of the images and their associated

times to pause between frames. There is also a class for each sprite,

holding various data.

I have read examples of other sprite collisions using pixel perfect

detection, and I understand that they access the pixel data of the overlap

of the image RECTs and loop through every pixel in the overlapping

rectangle, comparing pixel data each time to check for 2 non-alpha pixels.
I

do not know how to access the pixel data of the image files, or in this
case>I suppose it would be the relevent surface. I do not know how to tell

whether the pixel being accessed has the same RGB values as the alpha

channel for that surface.

I hope I have made myself clear, please feel free to email me privately if

you have any questions.

Can anyone help me? Would I be better of using opengl for this, or is it

unneccesary? The style of game I am making is a third-person 1v1 combat

game, similar to mortal kombat. Thanks in advance for any help, advice,

links, or code examples you show me.

Regards,

James

You can find perfect pixel collision with SDL, written in C++ here:
http://eounicorn.sf.net.
(CVS version works better, but collisions code is unchanged for ages)On Mon, Mar 24, 2003 at 11:51:54AM -0000, James Pickard wrote:

I am new to this list, so hello to everyone. I am quite inexpeienced with
regards to c++ programming, so please bear with me, and if you have any
suggestions or advice please don’t hesitate to let me know.


Free Software - find interesting programs and change them
NetHack - meet interesting creatures, kill them and eat their bodies
Usenet - meet interesting people from all over the world and flame them
Decopter - unrealistic helicopter simulator, get it from http://decopter.sf.net

How about using a separate collision bitmap for every sprite that would
have one bit per sprite’s pixel, telling if this pixel collides or not?
I don’t think it’s good to create an artificial dependency between
whether a pixel is drawn/transparent and whether it collides with nearby
objects. Transparency and collisions are two separate things - you can
easily imagine sprites that have parts that are not transparent and
still do not collide (various kinds of smoke, halo etc.).

Sure, you could resolve such cases by adopting a policy that either a
sprite collides or it does not - then you can have a colliding spaceship
sprite and a non-colliding engine smoke sprite, combining them during
blitting. However, I’m not sure if this doesn’t bring about more
complexity than it solves.

latimeriusOn Mon, Mar 24, 2003 at 11:51:54AM -0000, James Pickard wrote:

I have read examples of other sprite collisions using pixel perfect
detection, and I understand that they access the pixel data of the
overlap of the image RECTs and loop through every pixel in the
overlapping rectangle, comparing pixel data each time to check for 2
non-alpha pixels. I do not know how to access the pixel data of the
image files, or in this case I suppose it would be the relevent
surface. I do not know how to tell whether the pixel being accessed
has the same RGB values as the alpha channel for that surface.

James Pickard wrote:

I have read examples of other sprite collisions using pixel perfect
detection, and I understand that they access the pixel data of the
overlap of the image RECTs and loop through every pixel in the
overlapping rectangle, comparing pixel data each time to check for 2
non-alpha pixels. I do not know how to access the pixel data of the
image files, or in this case I suppose it would be the relevent surface.
I do not know how to tell whether the pixel being accessed has the same
RGB values as the alpha channel for that surface.

It’s probably best to check against colour key info, the bits that are
not drawn to the screen will not collide.

When you have found out how to access the pixel data (I think it’s
better if you find out yourself), the the following library will be able
to solve you pixel perfect collision problem.

http://www.ifm.liu.se/~ulfek/projects/SCAM-current/doc/SCAM.html

This will work with open GL in otho mode (2d), if you create a bitmask
for all sprites that need collision detection, then check each one using
bounding boxes, if you get a collision on the bounding boxes, then check
using the bitmask and feed SCAM the offset that the bounding boxes
overlapped. The bitmask is just a set of on or off values, 1 for solid
pixel data and 0 for colour key.

Remember that for animated sprites you will need a bitmask for each
frame of animation. Bitmasks take up very little memory.

The quickest bouding box check (as far as I know) is to test if there is
no intersection, rather than check if there is an intersection. i.e:

if( x1<x2 && y1<y2 && x_size1<x_size2 && y_size2<y_size2 ) return
NO_COLLISION;

Something like that. There may of course be a faster way, but i’m just
trying not to get flamed.

HTH

  • Tom.

Tom Wilson wrote:

James Pickard wrote:

I have read examples of other sprite collisions using pixel perfect
detection, and I understand that they access the pixel data of the
overlap of the image RECTs and loop through every pixel in the
overlapping rectangle, comparing pixel data each time to check for 2
non-alpha pixels.

This seems like a pretty slow method, specially since you must lock
the surfaces for every test. At the very least it’ll be tricky to code
in a fast way for the many different pixel formats.

I do not know how to access the pixel data of the image files, or
in this case I suppose it would be the relevent surface. I do not
know how to tell whether the pixel being accessed has the same RGB
values as the alpha channel for that surface.

It’s probably best to check against colour key info, the bits that are
not drawn to the screen will not collide.

Yep, or use a threshold for collision in the alpha channel case.

When you have found out how to access the pixel data (I think it’s
better if you find out yourself), the the following library will be able
to solve you pixel perfect collision problem.

Yes, it’s good to know how to do this. If you get stuck you can have a
look at the getpixel function example in the SDL docs, or at the
relevant parts of the source of http://icculus.org/airstrike

http://www.ifm.liu.se/~ulfek/projects/SCAM-current/doc/SCAM.html

Please use http://www.ifm.liu.se/~ulfek/projects/bitmask-1.1.1.tar.gz
instead. It’s faster and also maintained.

This will work with open GL in otho mode (2d), if you create a bitmask
for all sprites that need collision detection, then check each one using
bounding boxes, if you get a collision on the bounding boxes, then check
using the bitmask and feed SCAM the offset that the bounding boxes
overlapped.

Actually the library also does a bounding box test, so you don’t need
to do that separately.

The quickest bouding box check (as far as I know) is to test if there is
no intersection, rather than check if there is an intersection. i.e:

if( x1<x2 && y1<y2 && x_size1<x_size2 && y_size2<y_size2 ) return
NO_COLLISION;

This seems like a bogus test, try something like

if ( x1 + x_size1 < x2 || y1 + y_size1 < y2 || x2 + x_size2 < x1 || y2 + y_size2 < y1 )
return NO_COLLISION;

Something like that. There may of course be a faster way, but i’m just
trying not to get flamed.

Well, if you have very many sprites (hundreds) you might want to use a
grid or some other way of sorting the sprites so that you don’t test
faraway sprites at all. Don’t do this until after you know that this
is a bottleneck though.

Regards,
Ulf