Hello all-
I'm looking for a good collision detection library. I tried compiling pmask (under linux) but got the following errors:
pmask.c: In function ‘install_pmask’: pmask.c:34: error: size of array ‘_compile_time_assert__’ is negative pmask.c: In function ‘init_pmask’: pmask.c:40: warning: unused variable ‘error’ pmask.c: In function ‘get_serialized_pmask_size’: pmask.c:105: warning: unused variable ‘words’
The other library that is available is ppcol, but that doesn't appear to be available anymore.
Anyone able to provide any help or suggest a different collision library?
I'm quite sure this is ppcol, happened to have it among my other "good to have" snippets =)
| 1 | #include "collide.h" |
| 2 | |
| 3 | /* collide_detect(x1, y1, sprite1, x2, y2, sprite2) |
| 4 | checks on a per-pixel basis whether two sprites collided |
| 5 | called 'pixel-perfect' collision detection |
| 6 | the sprite coordinates are given from the upper-left. |
| 7 | |
| 8 | The basic idea is to calculate the overlapping area of the two sprite |
| 9 | rectangles. If there is no overlap, return that the objects did not |
| 10 | collide. Otherwise, look at the pixels inside that area for both sprites. |
| 11 | If, for a given pixel, both sprites have solid colors (i.e. not the masked |
| 12 | color), then the sprites collided. */ |
| 13 | |
| 14 | int collide_detect(int xmin1, int ymin1, BITMAP *sprite1, int xmin2, int ymin2, BITMAP *sprite2) { |
| 15 | int xmax1 = xmin1 + sprite1->w, ymax1 = ymin1 + sprite1->h; |
| 16 | int xmax2 = xmin2 + sprite2->w, ymax2 = ymin2 + sprite2->h; |
| 17 | int xmin = max(xmin1, xmin2); |
| 18 | int ymin = max(ymin1, ymin2); |
| 19 | int xmax = min(xmax1, xmax2); |
| 20 | int ymax = min(ymax1, ymax2); |
| 21 | if (xmax <= xmin || ymax <= ymin) { return 0; } |
| 22 | int mask1 = bitmap_mask_color(sprite1); |
| 23 | int mask2 = bitmap_mask_color(sprite2); |
| 24 | for (int y = ymin; y < ymax; y++) { |
| 25 | for (int x = xmin; x < xmax; x++) { |
| 26 | int x1 = x - xmin1, y1 = y - ymin1; |
| 27 | int x2 = x - xmin2, y2 = y - ymin2; |
| 28 | int color1 = getpixel(sprite1, x1, y1); |
| 29 | int color2 = getpixel(sprite2, x2, y2); |
| 30 | if (color1 != mask1 && color2 != mask2) { return 1; } |
| 31 | } |
| 32 | } |
| 33 | return 0; |
| 34 | } |
And the header ...
Thanks
The compile_time_assert_ error message with PMASK there is because you compiled in an environment where "unsigned long int" is 64 bits, and pmask defaults to assuming that it's 32 bits. The third paragraph of the "PORTABILITY & PLATFORMS" section of the docs describes how to compile it in such an environment.
PPCOL will, I believe, in such an environment, will silently use twice as much memory, with half of it being never-modified zeroes.
edit: when writting my initial post I glanced at ixilioms, saw the "ppcol", and didn't read the quoted code. Now I notice that he didn't actually link to PPCOL, but instead quoted PPCOLs allegro-sprite-collision-checker. That code will probably work fine anywhere that Allegro works, though many people prefer the bitmask based functions offered by PMASK and PPCOL because they can be dramatically faster for medium-to-large sprites.
Oh yeah... kinda forget about 64bit problems like that sometimes. Thanks, I will look at the docs more closely this time:-[
This is kind of off the topic but one hint I can give you is to make all of your character move only by an interval of 4 and see if any of the tiles 4x4 are touching. Characters can vary their speeds by timing how often they move. The result is perfect collision detection with minimal effort. As of libraries that deal with collision detection I haven't heard of any, sorry.