Openlayer bitmap collision
peccos

How to make a collision between polygon and bitmap so that the polgon would either bounce back or just stop? I found some example code but i dont know either what to do after collision has happened or how to use those functions. Pretty poorly intorduced in manual.

#SelectExpand
1//lets assume the polygon moves like this 2px += speed * cos(direction); 3py += speed * sin(direction); 4 5 6Collision collision = myPolygon.GetCollision( *myBitmap.GetCollisionPoly(), 7 myPolygon.GetPlacement(), Placement( Vec2D( imgx, imgy ))); 8 9// Let's see if a collision has happened 10if( collision ) { 11 // Get the exact point of the collision 12 Vec2D collisionPoint = collision.GetPoint(); 13 14 // Get the normal of the polygon at the collision point 15 Vec2D polyNormal = collision.GetNormal( OBJ_A ); 16 17 // Get the normal of the edges of the Bitmap at the collision point 18 Vec2D bitmapNormal = collision.GetNormal( OBJ_B ); 19}

GClaudiu

If all you need is detecting collision between two "objects" (by object I mean bitmap, polygon, whatever is drawn on the screen and you know it's size and position) you can simply use the bounding box method. Works preety good in most of the cases.

If you want a "pixel perfect" collision detection just use the getpixel() function to check when two pixels that aren't invisible (in allegro that would be R 255 G 0 B255) collide with each other. The cons of this method is that it's slower, esspecially when checking a lot of objects.

After you figure out the collision detection method just change the position of the objects accordingly (also the speed or whatever other variables you have to modify the movement of the objects).

Start of with to rectangles, it's easier.

#SelectExpand
1// Check collision. Make rect color red if collided, blue otherwise 2if (((x+10 > x2) && (y+10 > y2) && (x+10 < x2+10) && (y+10 < y2+10)) 3 || ((x2+10 > x) && (y2+10 > y) && (x2+10 < x+10) && (y2+10 < y+10))) 4 theColor = makecol (255, 0 , 0); 5else theColor = makecol (0, 0, 255); 6 7// Your objects 8rect(buffer, x, y , x+10, y+10, theColor); 9rect(buffer, x2, y2, x2+10, y2+10, theColor); 10 11// Blit to the screen 12blit(buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H); 13 14// Use this so you can move your objects around 15if (key[KEY_RIGHT]) x++; 16if (key[KEY_LEFT]) x--; 17if (key[KEY_UP]) y--; 18if (key[KEY_DOWN]) y++; 19 20if (key[KEY_D]) x2++; 21if (key[KEY_A]) x2--; 22if (key[KEY_W]) y2--; 23if (key[KEY_S]) y2++;

This is written on the fly, hope it works well. Also it's supposed to work in Allegro, didn't use OpenLayer before. For bouncing and stuff you have to modify the part where I changed the color to red with changing position or something. That's more complex, involving speed, gravity, friction, depends on how real you want it to look.

Good luck, hope this helps.

peccos

I believe i should use those OL:s own functions but i don't know how. I can detect collision but no idea how to use those GetPoint / GetNormal commands.

Fladimir da Gorf

OL doesn't know what a collision means in your case. For starters, you could move the polygons away of each other until no collision happens. But there are a lot of articles in the net about 2D collision physics, and those algorithms use the provided functions (normal, point etc). OL is mostly just graphics library, not physics...

This is written on the fly, hope it works well. Also it's supposed to work in Allegro, didn't use OpenLayer before.

Using OL's collision methods is much easier than even a bounding box... and compared to pixel-perfect collisions, they support rotated and stretched bitmaps. The example code is pasted there above.

Quote:

If all you need is detecting collision between two "objects"

Nope, he wants to know what he should do after the collision is detected...

GClaudiu

@Fladimir
Hehe, I told you I don't know OpenLayer :P

@peccos
If you figured out how to detect collision, could you give us an example of what exactly would you like to make?
For example: I want to have a ball bouncing on the screen.

You really have to know what you want to do in order to know what you have to do to achieve it (sound really funny, hope you understand). You won't be using the same code when collision occurs in a breakout clone as what you're using in a role playing game :)

peccos

Okay, the plan is to use a one big bitmap or either create a map from smaller bitmaps so i can accomplish a destructable terrain. if you have ever played Wings etc. you know how it's gonna be. If your player collides with the map it won't go through it from any angle I believe this pixel perfect method would work but am i supposed to use allegros commands or can this be done only with OL?

GClaudiu

Is this about the MC2 project? Collision masks are the way to go, so for every frame of the animation of a worm you would have a black and white mask, with white meaning "this is a pixel that's part of the worm" and black "this is invisible, doesn't collide".

You'll have the same collision mask for the map, that can be generated at runtime, once with the terrain.

Now say you have a grenade launched, that should also have a collision mask. When the grenade hits the terrain, render the explosion. The explosion should have something like a big circle attached, sort of like the collision mask.

So, when the explosion is rendered you just have to tell the program to replace every pixel on the terrain with an alpha pixel if that explosion circle overlaps it.

Like that you'll have a hole on the terrain once the grenade exploded. For a nicer effect, you could double the terrain layer, meaning that you'll have two identical terrains overlapping each-other. When the grenade explodes, replace the pixels on the ON TOP terrain layer with alpha pixels, and do the same with the layer behind as well, but make sure it's a circle with a smaller radius. Like that you'll give a sense of depth to the hole made on the terrain.

Use trigonometry functions if you want to make the grenade to bounce from the ground up at an angle, but that's another story. For your example all you have to do is change the grenade in mid air animation (maybe just a spinning grenade) with an exploding animation when it detects collision (make sure you stop moving the grenade when it hits the ground).

Oh, and do not use a big bitmap, not a good idea really (imagine a 3000*1000 sized map...). Maybe try tiles if you really want images, but you can also generate a random sloping terrain on run-time

peccos

Okay i gave up with those OL functions for a while, always ended up giving wrong positions of collision argh. I tried OL:s GetPixel to check one pixels color from the player but this slowed down the game 90%. How am i supposed to use it? Lets say color white is considered transparent and black the terrain. Do i check if some pixel in player bitmap is black and if so then collision happens?

Edit: So i believe i have to deal with memory bitmaps to make it faster. I tried to convert OL bitmap into memorybitmap but it seems not to load it correctly. Same thing i tried to load an allegro bitmap but when drawing it only shows a black box instead. OL:s getpixel didn't work with memory bitmaps so should i be able to use allegros getpixel? Or perhaps there is another way of doing all this?

Thread #599634. Printed from Allegro.cc