Jump to content

  • Log In with Google      Sign In   
  • Create Account

We're offering banner ads on our site from just $5!

1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


SDL Collision Library


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
22 replies to this topic

#1 CaptCanada   Members   -  Reputation: 224

Like
0Likes
Like

Posted 26 March 2005 - 09:18 AM

Hi everyone, I am just wondering if there is a nice SDL collision library out there? I am coding a lunar lander game and need some help checking for collions with the mountains in the game. Thanks

Sponsor:

#2 Drew_Benton   Crossbones+   -  Reputation: 1719

Like
0Likes
Like

Posted 26 March 2005 - 09:22 AM

I was mistaken, there are a few [smile]. One of them is this one. From what I have seen on google, it is the best for SDL. You can also look at some concepts that are used with Lesson 6 of Cone3D's, but that Bitmask Collision Library should be what you need.

- Drew

#3 CaptCanada   Members   -  Reputation: 224

Like
0Likes
Like

Posted 26 March 2005 - 09:35 AM

Thanks!


#4 Rob Loach   Moderators   -  Reputation: 1500

Like
0Likes
Like

Posted 27 March 2005 - 03:01 PM

There is SDL_Collide.h which provides a couple of functions to have bitmask collision detection. I would recommend using a different method of checking collisions though as checking through overlapping pixels can slow down the game. Try bounding box collision or bounding circle collision test. If you don't need that much precision with what you want to collide, those are very fast.

Rob Loach [Website] [Projects] [Contact]

#5 Genjix   Banned   -  Reputation: 100

Like
0Likes
Like

Posted 27 March 2005 - 09:13 PM

the above also does bounding box collisions.

#6 relsoft   Members   -  Reputation: 255

Like
0Likes
Like

Posted 27 March 2005 - 10:48 PM

Genjix's routines should be fast enough even on arcade shooters. Looking at his code, it does the pixel perfect collision with overlapping pixels. In my experience, even in sofware, it should be fast enough.

#7 evillive2   Members   -  Reputation: 694

Like
0Likes
Like

Posted 28 March 2005 - 03:54 AM

It should also be mentioned that the code linked to above assumes each sprite has it's own surface as opposed to belonging o a sprite sheet (if I read it correctly). It shouldn't be difficult to modify to accept 2 extra SDL_Rect structures though. On another note, using the bounding box collision detection to find a collision and THEN using the pixel perfect collision to refine that collision if it occurs would probably be the more efficient way to get pixel perfect collision in your game as in most cases more than half of the checks do not return a collision. That way you only check the slower pixel perfect routines if you need to.

@Genjix
nice job :) I am sure that will help a lot of people.


Evillive2

#8 CaptCanada   Members   -  Reputation: 224

Like
0Likes
Like

Posted 28 March 2005 - 07:18 AM

My spaceship is a seperate surface as well as the mountians. I was thinking of a bounding box collision test,but since the rect a mountian would be huge compared to the ship, it would result in a false collision detection right?

I am very newbie when it comes to collision detection beyond bounding boxes, so anything that allows me to simply test for collisions between two objects is great. Kinda like a "collision detection library for dummies" is ideal.

Thanks


#9 Genjix   Banned   -  Reputation: 100

Like
0Likes
Like

Posted 28 March 2005 - 01:07 PM

Quote:
Original post by evillive2
On another note, using the bounding box collision detection to find a collision and THEN using the pixel perfect collision to refine that collision if it occurs would probably be the more efficient way to get pixel perfect collision in your game as in most cases more than half of the checks do not return a collision. That way you only check the slower pixel perfect routines if you need to.

pixel perfect test already does that (how can i compute overlaps, if it doesn't exist?) ;)

Quote:
Original post by evillive2
@Genjix
nice job :) I am sure that will help a lot of people.

thanks. I'm not sure why SDL doesn't have something similar (what with all the unnecessary libs like reading audio cds).

I might extend it, if anyone finds it useful(i.e a circle collision test and add skips - instead of reading every pixel, read every nth pixel using extra param
int skip = 0
).

#10 Rob Loach   Moderators   -  Reputation: 1500

Like
0Likes
Like

Posted 28 March 2005 - 02:37 PM

Quote:
Original post by Genjix
...
I wrote up a bounding circle collision test function a while ago if you're too lazy to write one yourself [smile].

Rob Loach [Website] [Projects] [Contact]

#11 Kylotan   Moderators   -  Reputation: 3338

Like
0Likes
Like

Posted 28 March 2005 - 04:21 PM

Quote:
Original post by Genjix
thanks. I'm not sure why SDL doesn't have something similar (what with all the unnecessary libs like reading audio cds).


SDL wraps platform dependent functionality in an platform independent way. How to access audio cds is different on Linux and Windows but collision detection is nothing to do with the platform.

#12 Genjix   Banned   -  Reputation: 100

Like
0Likes
Like

Posted 29 March 2005 - 04:35 AM

Quote:
Original post by Rob Loach
Quote:
Original post by Genjix
...
I wrote up a bounding circle collision test function a while ago if you're too lazy to write one yourself [smile].

i assume you do something like test if the distances between the 2 points is less than the sum of the radii?... but yeah, give it to me (include your name/email for credit). I spose I should split it into a header and source now.

What do you think of names
SDL_CollidePixel(SDL_Surface*,int,int , SDL_Surface*,int,int , int skip = 0)
SDL_CollideBounding(int,int,int,int , int,int,int,int)
SDL_CollideBounding(SDL_Rect,SDL_Rect)
SDL_CollideCircle(int,int , int,int)


#13 Rob Loach   Moderators   -  Reputation: 1500

Like
0Likes
Like

Posted 29 March 2005 - 06:12 AM

I'd personally would rather have:
SDL_CollidePixel( ... )
SDL_CollideBoundingBox( ... )
SDL_CollideBoundingBox( ... )
SDL_CollideBoundingCircle( ... )

... But that's just me.


As for the credit, just put in "Rob Loach (http://www.robloach.net)" anywhere in there. I'm not really that anal about this kind of thing. You can reformat the documentation as much as you want. I wasn't quite sure about the second SDL_CollideBoundingCircle as sometimes a sprite can be only part of an SDL_Surface......


// Declaration (*.h)
bool SDL_CollideBoundingCircle(int x1, int y1, int radius1, int x2, int y2, int radius2, int offset = 0);
bool SDL_CollideBoundingCircle(SDL_Surface* a, int x1, int y1, SDL_Surface* b, int x2, int y2, int radius1 = -1, int radius2 = -1, int offset = 0);



// Definition (*.cpp)


#include <cmath>

// SDL_CollideBoundingCircle(x1, y1, radius1, x2, y2, radius2, offset)
// Checks a collision using the bounding circle of two different sprite objects
// x1 - The x center position of the first object
// y1 - The y center position of the first object
// radius1 - The radius of the first object
// x2 - The x center position of the second object
// y2 - The y center position of the second object
// radius2 - The radius of the second object
// offset - Allow some offset between the two objects (0 default)

bool SDL_CollideBoundingCircle(int x1, int y1, int radius1, int x2, int y2, int radius2, int offset){
int distx = abs((int)(x1 - x2));
int disty = abs((int)(y1 - y2));
return(sqrt((distx * distx) + (disty * disty)) - radius1 - radius2 <= offset);
}



// SDL_CollideBoundingCircle(a, x1, y1, b, x2, y2, radius1, radius2, offset)
// Checks a collision using the bounding circle of two different sprite objects
// a - The SDL_Surface of the first object
// x1 - The left position of the first object
// y1 - The y center position of the first object
// radius1 - The radius of the first object (-1 defaults to the average of the width and height of the surface)
// b - The SDL_Surface of the second object
// x2 - The x center position of the second object
// y2 - The y center position of the second object
// radius2 - The radius of the second object (-1 defaults to the average of the width and height of the surface)
// offset - Allow some offset between the two objects (0 default)

bool SDL_CollideBoundingCircle(SDL_Surface* a, int x1, int y1, SDL_Surface* b, int x2, int y2, int radius1, int radius2, int offset){
if(radius1 == -1) radius1 = (a->w * a->h) / 2;
if(radius2 == -1) radius2 = (b->w * b->h) / 2;
x1 = x1 + a->w/2;
y1 = y1 + a->h/2;
x2 = x2 + b->w/2;
y2 = y2 + b->h/2;
int distx = abs((int)(x1 - x2));
int disty = abs((int)(y1 - y2));
return(sqrt((distx * distx) + (disty * disty)) - radius1 - radius2 <= offset);
}







You can reformat anything as much as you want, I don't mind. You'll have to re-do the documentation to fit into the SDL_Collide.h formatting. Remember that I'm not quite sure about using the second SDL_CollideBoundingCircle as sometimes a sprite can be only part of a SDL_Surface (tiles). I also have yet to compile these renditions, so don't freak out if it pops up a couple of errors.

[Edited by - Rob Loach on March 29, 2005 12:12:51 PM]

Rob Loach [Website] [Projects] [Contact]

#14 Kylotan   Moderators   -  Reputation: 3338

Like
0Likes
Like

Posted 29 March 2005 - 08:50 AM

As an aside on performance, It may be more efficient to square the radii than to take the square root of the distance.

#15 Genjix   Banned   -  Reputation: 100

Like
0Likes
Like

Posted 02 April 2005 - 05:40 AM

there you go, a nice new updated SDL Collision library for the community SDL Collide (ive left the original library intact for beginners who may not know how to link, or just want to know the implementation). Feedback welcome.

#16 Rob Loach   Moderators   -  Reputation: 1500

Like
0Likes
Like

Posted 03 April 2005 - 12:56 PM

Very cool, I like it .

One thing though, sometimes you have more then one image on a surface (tiled images), this would mean that the SDL_CollidePixel function wouldn't work. To have it work correctly with a tiled surface image, you'd have to have:
SDL_CollidePixel(SDL_Surface* image1,
int image1TileWidth, int image1TileHeight,
int image1TileX, int image1TileY,
int image1x, int image1y,
SDL_Surface* image2,
int image2TileWidth, int image2TileHeight,
int image2TileX, int image2TileY,
int image2x, int image2y);

... Lots of arguments.... hah, I'll have a stab at it once I get the time.

Rob Loach [Website] [Projects] [Contact]

#17 Ravuya   Moderators   -  Reputation: 127

Like
0Likes
Like

Posted 04 April 2005 - 05:26 AM

This article may help you formulate your own algorithm.

#18 Rob Loach   Moderators   -  Reputation: 1500

Like
0Likes
Like

Posted 06 April 2005 - 03:13 PM

Quote:
Original post by Ravuya
This article may help you formulate your own algorithm.
Hmmmm, just doing some thinking out loud here... What if you created a bitmask and then made up a polygon to best fit the bitmask. You could then use that new polygon in the collision detection for some awesome speed in collision detection.

Rob Loach [Website] [Projects] [Contact]

#19 scpedicini   Members   -  Reputation: 122

Like
0Likes
Like

Posted 15 April 2005 - 04:23 AM

I was looking at the SDL_CollidePixel function and noticed two things that I think might cause a problem.



After the nested For-Loops, you don't have a return value; just for the sake of type-correctness, it should probably return a 0 value.

In the nested for-loops you have the line:



if((SDL_CollideTransparentPixelTest(as , x-ax , y-ay)) && (SDL_CollideTransparentPixelTest(bs , x-bx , y-by)))
return 1;



Shouldn't this be:



if((!SDL_CollideTransparentPixelTest(as , x-ax , y-ay)) && (!SDL_CollideTransparentPixelTest(bs , x-bx , y-by)))
return 1;




If both overlapping pixels are not transparent, then a collision has occurred.

Just thought I'd mention it,
Shaun

#20 steveski74   Members   -  Reputation: 122

Like
0Likes
Like

Posted 27 May 2006 - 04:38 AM

Hi,

I know this is a long time since the last post, but I'm replying in case someone else stumbles across the thread.

Another nice efficient way to determine collisions is to define a list of points representing a collision polygon in your sprite class.
You pass this point list along with the point to check for into a function which does some cool stuff.
This function should loop through the list of points in pairs.
you determine the angle between the 2 collision poly points and the single point your checking against.
Once you've checked every pair of points in the list, if all the angle added together = 360 degrees then you have a collision.
It's nice to see basic year 7 maths coming back into the picture ;)

This is only to check if a single point entres a polygon, but some simple tweaking could have you have you passing more info into the collision routine if needed.

Anwyay, I though it may interest someone.

Have fun




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS