PDA

View Full Version : Collision detection problem


BSi
10-12-2006, 11:54 AM
I'we just found an annoying problem in the collision detection logic in PPL. I'm currently working on a simple platform game and I plan to use small boxes as platform elements. I don't want to create new bitmaps for each platform length so I use a base platform element and replicate it as many times as how long I plan to build the current platform.

See code below:
platform1$ = loadsprite(AppPath$ + "platform.bmp", -1, 1, 0, NULL);
MoveSprite(platform1$, 15, 280);
SetSpriteOptions(platform1$, SO_FIXEDX | SO_COLLIDE | SO_CHECKCOLLIDE | SO_ACCURATECHECK);
SetSpriteTileX(platform1$, 10);
SetSpriteId(platform1$, "PLATFORM");

platform2$ = loadsprite(AppPath$ + "platform.bmp", -1, 1, 0, NULL);
MoveSprite(platform2$, 120, 250);
SetSpriteOptions(platform2$, SO_FIXEDX | SO_COLLIDE | SO_CHECKCOLLIDE | SO_ACCURATECHECK);
SetSpriteTileX(platform2$, 5);
SetSpriteId(platform2$, "PLATFORM");

player$ = loadsprite(AppPath$ + "player.bmp", g_rgb(255, 0, 255), 1, 0, NULL);
MoveSprite(player$, 30, 200);
SetSpriteOrder(player$, 100); // display player on the top of other level elements (Z-Order setting)
SetSpriteOptions(player$, SO_COLLIDE | SO_CHECKCOLLIDE | SO_ACCURATECHECK);
SetSpriteMass(player$, 1);
SetSpriteGravity(player$, 0.001);
SetSpriteId(player$, "PLAYER");
SetSpriteCollide(player$, "PLATFORM");


So the problem is that if I 'scretch' a platform element horizontally with SetSpriteTileX(), the collision detection will be executed only if the player hits the original short platform element, but no collision at all it the player hits the tiled parts of the platform.

How can I work out this problem?

BSi
10-12-2006, 12:08 PM
In the meantime I found a quick solution: SetSpriteCollideRect() for each platform

MagNet
10-12-2006, 02:46 PM
I think there's a function to update it automatically but I haven't ever used it... I'll try to find it.

EDIT:
Maybe there isn't such function hm... but I was quite sure there is, but I can't seem to find it.

BSi
10-12-2006, 05:01 PM
I'm still playing around this repeating platform collision thing and found another weirdness. It seems that the execution order of each sprite manipulation functions is very important, but it's not documented in the manual.

My first try looked like this:

platform1$ = loadsprite(AppPath$ + "platform.bmp", -1, 1, 0, NULL);
MoveSprite(platform1$, 30, 200);
SetSpriteOptions(platform1$, SO_COLLIDE | SO_CHECKCOLLIDE);
SetSpriteTileX(platform1$, 5);
SetSpriteCollideRect(platform1$, 0, 0, 200, 10);
SetSpriteId(platform1$, "PLATFORM");


If you try this, you'll find that the collision will be calculated for a rectangle of (0, 0, 60, 10). Weird.

But if I change the execution order of the code lines to this:


platform1$ = loadsprite(AppPath$ + "platform.bmp", -1, 1, 0, NULL);
MoveSprite(platform1$, 30, 200);
SetSpriteOptions(platform1$, SO_COLLIDE | SO_CHECKCOLLIDE);
SetSpriteId(platform1$, "PLATFORM");
SetSpriteTileX(platform1$, 5);
SetSpriteCollideRect(platform1$, 0, 0, 200, 10);


everything works perfect, I got the defind (0, 0, 200, 10) collision box working. Why?

kornalius
10-12-2006, 06:36 PM
Tiling sprites won't expand the collision detection of the sprite.

I have fixed the SetSpriteCollideRect() not to be reset when some functions (like SetSpriteId) are used after.