Tilemap collision

Started by
14 comments, last by Jesperklippel 8 years, 10 months ago

for(int i = 0; i < HEIGHT; i++)
		{
			for(int j = 0; j < WIDTH; j++)
			{
				if(level1.level[i][j] == 1)
				{
					//Bottom, top, left and right position of the tile.
					int bottom, top, left, right;
					bottom = i*32 + 32;
					top = i*32;
					left = j*32;
					right = j*32 + 32;

					if(player.right < left || player.left > right || player.top > bottom || player.bottom < top)
					{

					}
					else
					{
						std::cout << "Collision!";
					}
				}

Okay so I got this working. It's outputting Collision at the right times!
Now, how should I stop the player from moving? This is also something that I don't really get. Should I set the position, set the move speed to 0?

- Jesper

Advertisement
in your player.cpp only set velocity.x to moveSpeed when there isn't any collision. save the collision in a boolean variable. check my previous posts for more info about my hacky way, or view other people's responses if you want to implement those.

I've tried that too.. I've tried everything. I'm desperate... What is a game without collision? The interview I have is tomorrow..... :(

I hope that it wouldn't come to this, but here is the project: https://drive.google.com/file/d/0BySRvoxEoAtlTm8wMVVsN3B3TFU/view?usp=sharing

I'd appreciate it sooo much if you would take a look, or try anything, because I don't know what to do anymore.. Thank you so much!

- Jesper

hi, i'll have a look at it now. just one thing i found:


top = player.getPosition().y;
bottom = player.getPosition().y + 7.5;
left = player.getPosition().x;
right = player.getPosition().x + 7.5;

top, bottom, left and right are integers. you cant assign a floating point number, it will alwayxs be converted to an integer, most likely rounded down. I dont know if you are aware of that. As already stated you are mixing ints and floats a lot which can cause random trouble.

Sorry, took me a while to compile it in code::blocks (Somehow i picked the win32 bins instead of the gcc ones... not a good idea obviously...)

Actually it is working just fine with the attempt i wrote about earlier (see 25th May):


sf::Vector2f PlayerPos = player.player.getPosition();
sf::Vector2i PlayerTile = sf::Vector2i(PlayerPos.x / 32.0f, PlayerPos.y / 32.0f);
if(player.upPressed)
{
	float Line = (float)PlayerTile.y * 32.0f + 7.5f;
	float Remainder = std::fmod(PlayerPos.x, 32.0f);
	int Offset = 0;
	if(Remainder < 7.5f)
		Offset = -1;
	else if(Remainder > 32.0f - 7.5f)
		Offset = 1;
	if((level.level[PlayerTile.y-1][PlayerTile.x] == 1 || level.level[PlayerTile.y-1][PlayerTile.x+Offset] == 1) && PlayerPos.y < Line)
		PlayerPos.y = Line;
}
else if(player.downPressed)
{
	float Line = (float)PlayerTile.y * 32.0f + 32.0f - 7.5f;
	float Remainder = std::fmod(PlayerPos.x, 32.0f);
	int Offset = 0;
	if(Remainder < 7.5f)
		Offset = -1;
	else if(Remainder > 32.0f - 7.5f)
		Offset = 1;
	if((level.level[PlayerTile.y+1][PlayerTile.x] == 1 || level.level[PlayerTile.y+1][PlayerTile.x+Offset] == 1) && PlayerPos.y > Line)
		PlayerPos.y = Line;
}
else if(player.rightPressed)
{
	float Line = (float)PlayerTile.x * 32.0f + 32.0f - 7.5f;
	float Remainder = std::fmod(PlayerPos.y, 32.0f);
	int Offset = 0;
	if(Remainder < 7.5f)
		Offset = -1;
	else if(Remainder > 32.0f - 7.5f)
		Offset = 1;
	if((level.level[PlayerTile.y][PlayerTile.x+1] == 1 || level.level[PlayerTile.y+Offset][PlayerTile.x+1] == 1)&& PlayerPos.x > Line)
		PlayerPos.x = Line;
}
else if(player.leftPressed)
{
	float Line = (float)PlayerTile.x * 32.0f + 7.5f;
	float Remainder = std::fmod(PlayerPos.y, 32.0f);
	int Offset = 0;
	if(Remainder < 7.5f)
		Offset = -1;
	else if(Remainder > 32.0f - 7.5f)
		Offset = 1;
	if((level.level[PlayerTile.y][PlayerTile.x-1] == 1 || level.level[PlayerTile.y+Offset][PlayerTile.x-1] == 1) && PlayerPos.x < Line)
		PlayerPos.x = Line;
}
player.player.setPosition(PlayerPos);

Just put this above the for loop and delete your old collision code for the player in the for loop.

Furthermore you have to call the Move Functions and execute the code which updates the positions of objects relative to the player and the update of the sf::View AFTER the collision stuff but before rendering.

Furthermore make sure to call the move functions and update functions before doing the collision stuff, then execute the code which updated the positions of objects relative to the player and the sf::View. After those steps, in that order, render everything. (In you current code you are first checking for collisions, then call the move functions and then render which would cause some jitter)

That way it is working fine over here.

EDIT: oh an you will have to include the cmath header in main.cpp. If you still have questions regarding the code you can pm me

EDIT2: moreover, you will probably have to fix the enemies... sometimes they are getting stuck because you just negate the velocity (and sometimes they slowly travel through walls because of that and non-fixed timesteps). Additionally, You should kind of "pause" the game when the player is dead or he is done with the level. The way it is now one could finish level1 and then still run into the enemies losing lifes.

3pic_F4il_FTW came with a solution! Thanks! :D

- Jesper

This topic is closed to new replies.

Advertisement