Page 1 of 1

Tile maps collision detection on top-down view. C++/Allegro.

Posted: Sat Jul 24, 2010 3:55 pm
by fryz
Hi everybody! I am again confused about some things. I don't actually know how to make tile maps detect, if you are entering in a forbidden tile! I think about it this way: You go trough road tiles (let's say array image number 1). If you enter array image number two, i are stopped, as it detects collision. But i really cannot manage to do it. Can anyone help me with that? This time i mean, that i don't even have an idea on how to do it.

P.S. By the way, someone has posted Allegro forums earlier, but i cannot enter them, anybody know why? I have tried googling them, but still cannot.

Re: Tile maps collision detection on top-down view. C++/Allegro.

Posted: Sun Jul 25, 2010 12:37 am
by isamgray
Quick question(so I can give you the easiest answer to your question)...Are you doing a pixel, or tile movement? Like, each time the player presses the up arrow, does he move a certain number of pixels, or just one tile up?

Re: Tile maps collision detection on top-down view. C++/Allegro.

Posted: Sun Aug 01, 2010 12:11 pm
by fryz
Hi. Sorry, i was very busy with other things past few days, looks like it's almost done (not programming), so it looks like i can be back to programming stuff. :)

I'm doing pixel movement. But actually tile movement is quite a good idea for such a game, haven't even thought of "tile movement"... Could you please help me with both, different versions?

As for tile movement it's like if(key[UP]){char_y + 32;}, right? According, that one tile is 32x32px.

Re: Tile maps collision detection on top-down view. C++/Allegro.

Posted: Sun Aug 01, 2010 1:37 pm
by dandymcgee
fryz wrote: As for tile movement it's like if(key[UP]){char_y + 32;}, right? According, that one tile is 32x32px.
Yup. And isamgray's question was very important, because collision in a tile-based world is going to be drastically simpler. Why?

If movement is based on pixels you'll likely be using a bounding box (an invisible rectangle representing the collidable area of an object) collision system. If these invisible boxes overlap, a collision has occurred and must be resolved appropriately.

In a tile-based world collision it is as simple as giving each tile a "solid" attribute and a simple check before moving the player. If the tile you will be moving onto is solid, leave the player where he stands. Otherwise, move the player to that tile. Think of it like a very simple game of chess where you control a single King and every one of your enemy's pieces is a solid brick wall who's square you may not walk on.

If you decide that pixel-based movement is still a must, post back here and perhaps we can example the slightly more advanced collision methods involving bounding boxes (or perhaps google "AABB collision" or "rectangle bounding box").

Re: Tile maps collision detection on top-down view. C++/Allegro.

Posted: Sun Aug 01, 2010 1:58 pm
by fryz
Thanks for your explanation.

So basically i understand the principle of tile collision yea, but how to do it i'm not sure:

Check on what number in the map array player steps, and if it is (let's say the normal walkable ground is 0 and the wall is 1 for simplicity) 1, then just do nothing. Leave an empty if statement. And else it is 0, then the position advances by 32 pixes. Right?

Okay, now for pixel collision... Well, my next game is gonna be a snake clone, so i'm going to need the pixel collision. For this game and learning purposes, i can use the tile collision. So yea, i would like to receive some help about that kind of collision on a tile map.

Re: Tile maps collision detection on top-down view. C++/Allegro.

Posted: Sun Aug 01, 2010 8:39 pm
by dandymcgee
fryz wrote: Check on what number in the map array player steps, and if it is (let's say the normal walkable ground is 0 and the wall is 1 for simplicity) 1, then just do nothing. Leave an empty if statement. And else it is 0, then the position advances by 32 pixes. Right?
Well there's never any point to an empty if statement.

Code: Select all

if( tileWalkingOnto.walkable == true ) {
    player.Move();
}
If it's not true no Move() call, unnecessary to put an empty statement explicitly for that situation.
fryz wrote: Okay, now for pixel collision... Well, my next game is gonna be a snake clone, so i'm going to need the pixel collision. For this game and learning purposes, i can use the tile collision. So yea, i would like to receive some help about that kind of collision on a tile map.
Basic AABB collision. If the two rectangles representing the snake and the food are colliding, call the EatFood() function.

Psuedo-code (this will actually crash due to uninitialized variables):

Code: Select all

struct Snake {
	int x;
	int y;
	int w;
	int h;
	void EatFood(){ return; }
};

struct Food {
	int x;
	int y;
	int w;
	int h;
};

//Simplest rectangle collision test.
//Provides only a boolean result (true or false).
//If you need more information (ie. which sides collided) this method will not do.
bool checkCollision(Snake *player, Food *apple) {
	if((player.x < apple.x + apple.w) && (player.x + player.w > apple.x) && (player.y < apple.y + apple.h) && (player.y + player.h > apple.y)) {
		return true;
	}
	return false;
}

int main() {
	Snake *player = new Snake();
	Food *apple = new Food();
	while( !quit ) {
		if( checkCollision(player, apple) ) {
			Snake.EatFood();
			quit = true;
		}
	}
	return 0;
}
That's all there is to it. ;)

Re: Tile maps collision detection on top-down view. C++/Allegro.

Posted: Mon Aug 02, 2010 7:35 am
by fryz
Okay, thanks for the explanations, very nicely done, explained a lot, give me a few nice ideas how to do other, related stuff. But now i have tried to do that thing i was talking in the last post, tile movement:

My tile size is 32px. When i write the code like this:

Code: Select all

	if(key[KEY_DOWN])
	{
		player_y  = player_y + 32;
		keypress = 2;
	}
Well, it jumps almost trough all the screen... I have tried lowering the time counter to 5 and 10, just for testing purposes. The character's moved very edgy and still incredibly fast. Looks like i fail something on the tile movement, don't i?

Here is my logic thinking:

If the player presses a key, the guy moves a tile to the side the player pressed the button. It is by 32 pixels, since the tile size is 32px. But then again, logically if player HOLDS they key, the guy keeps moving. Also, if i slow down the movement in some way (use wait()? Or sleep(), i don't quite remmeber, need to check in the tutorial of Allegro basics, haven't used this thing.), the movement looks edgy. So to avoid this, i should do a game, which is based on this movement. OR limit the keypress like that:

Code: Select all

int keypress = 0;
while(!quit)
{
if(key[KEY_UP])
     key_press = 1;
keypress = 0;
if(keypress == 1)
     player_y = player_y - 32;
}
Am i right somewhere?

Okay, going to try tht ball accelleration thing, you gave me tips about, rised me some ideas how to make it work.
Thanks for your answers, really helps a lot. :)

Re: Tile maps collision detection on top-down view. C++/Allegro.

Posted: Mon Aug 02, 2010 3:01 pm
by dandymcgee
fryz wrote: Also, if i slow down the movement in some way (use wait()? Or sleep(), i don't quite remmeber, need to check in the tutorial of Allegro basics, haven't used this thing.), the movement looks edgy. So to avoid this, i should do a game, which is based on this movement. OR limit the keypress like that:
In SDL there's an SDL_EnableKeyRepeat() function which can be used to set the delay between repeated keys to a higher value. I'd imagine there's something similar in Allegro, check the docs.

Re: Tile maps collision detection on top-down view. C++/Allegro.

Posted: Mon Aug 02, 2010 4:06 pm
by fryz
I think this might be the thing:

http://alleg.sourceforge.net/stabledocs ... board_rate

But there aren't even a single explanation or example how to use it. Tried using it like a function, might define something, but no effect, also like a variable... Anyway, going to try the collision thing, with the fast, edgy movement.

Re: Tile maps collision detection on top-down view. C++/Allegro.

Posted: Mon Aug 02, 2010 4:40 pm
by dandymcgee
void set_keyboard_rate(int delay, int repeat);
The function definition IS the explanation. You call the set_keyboard_rate() function with two integer parameters: the first being the delay after the initial key press to start repeating, the second being the delay between repeats. Both are in milliseconds.

BTW, that's a function reference, not proper documentation. Hence the lack of any in-depth explanation.