Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » collision

This thread is locked; no one can reply to it. rss feed Print
collision
spork222
Member #7,263
May 2006

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?

ixilom
Member #7,167
April 2006
avatar

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 
14int 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 ...

#ifndef COLLIDEH
#define COLLIDEH
#include <allegro.h>
#include <math.h>
#define max(a, b) (((a) > (b)) ? (a): (b))
#define min(a, b) (((a) < (b)) ? (a): (b))

int collide_detect(int xmin1, int ymin1, BITMAP *sprite1, int xmin2, int ymin2, BITMAP *sprite2);
#endif

___________________________________________
Democracy in Sweden? Not since 2008-Jun-18.
<someone> The lesbians next door bought me a rolex for my birthday.
<someone> I think they misunderstood when I said I wanna watch...

spork222
Member #7,263
May 2006

Thanks ;D

orz
Member #565
August 2000

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.

spork222
Member #7,263
May 2006

Oh yeah... kinda forget about 64bit problems like that sometimes. Thanks, I will look at the docs more closely this time:-[

Francois Lamini
Member #7,791
September 2006
avatar

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.

Francois

Go to: