1
General / Collision with tiles and a player
« on: November 18, 2014, 08:49:49 pm »
Hi,
I'm currently making a simple 2D side scroller for class with SFML 2.1 and I've ran into a bit of a collision issue.
My collision works fine as long as the player does not jump in a corner.
Or try to hug a wall mid-air.
If the player stand in a corner (on one tile, and right beside another)
And press the key to make the player move towards that tile while i press the jump key.
If i do this the player will jump for every tile (thinking it is standing on it) and fly into the air.
If the player hugs the wall in mid-air it lands on a tile in the wall making it seem like the player is floating in the air.
here (https://vid.me/fVyu) is a short clip showing off the weirdness.
My collision work the way that it just moves the player outside the tile it is colliding with, in a direction depending on which side the tile is hit.
I'm guessing my problem is with the intersection, in that it can intersect with more than one side.
Which means that when the player hugs the wall it collides with both the top and the left/right side of the tile.
My intersection code looks something like this:
If this returns true it calls a hit function that looks something like this:
Any help would be greatly appreciated.
I'm currently making a simple 2D side scroller for class with SFML 2.1 and I've ran into a bit of a collision issue.
My collision works fine as long as the player does not jump in a corner.
Or try to hug a wall mid-air.
If the player stand in a corner (on one tile, and right beside another)
And press the key to make the player move towards that tile while i press the jump key.
If i do this the player will jump for every tile (thinking it is standing on it) and fly into the air.
If the player hugs the wall in mid-air it lands on a tile in the wall making it seem like the player is floating in the air.
here (https://vid.me/fVyu) is a short clip showing off the weirdness.
My collision work the way that it just moves the player outside the tile it is colliding with, in a direction depending on which side the tile is hit.
I'm guessing my problem is with the intersection, in that it can intersect with more than one side.
Which means that when the player hugs the wall it collides with both the top and the left/right side of the tile.
My intersection code looks something like this:
if (objRect.top < tileRect.top && tileRect.top < (objRect.top + objRect.height) && (objRect.top + objRect.height) < (tileRect.top + tileRect.height))
hitBottom = (tileRect.top + tileRect.height) - objRect.top;
if ((tileRect.top + tileRect.height) > (objRect.top) && ((objRect.top + objRect.height) >(tileRect.top + tileRect.height)))
hitTop = (tileRect.top + tileRect.height) - objRect.top;
if (objRect.left < tileRect.left && tileRect.left < (objRect.left + objRect.width) && (objRect.left + objRect.width) < (tileRect.left + tileRect.width) && (objRect.top + objRect.height) > (tileRect.top + tileRect.height / 2))
hitLeft = (objRect.left + objRect.width) - tileRect.left;
if (objRect.left < (tileRect.left + tileRect.width) && objRect.left > tileRect.left && (objRect.left + objRect.width) >(tileRect.left + tileRect.width) && (objRect.top + objRect.height) >(tileRect.top + tileRect.height / 2))
hitRight = (tileRect.left + tileRect.width) - objRect.left;
if (hitLeft != 0)
tmpSides |= LEFT;
if (hitRight != 0)
tmpSides |= RIGHT;
if (hitTop != 0)
tmpSides |= TOP;
if (hitBottom != 0)
tmpSides |= BOTTOM;
if (sides)
*sides = tmpSides;
hitBottom = (tileRect.top + tileRect.height) - objRect.top;
if ((tileRect.top + tileRect.height) > (objRect.top) && ((objRect.top + objRect.height) >(tileRect.top + tileRect.height)))
hitTop = (tileRect.top + tileRect.height) - objRect.top;
if (objRect.left < tileRect.left && tileRect.left < (objRect.left + objRect.width) && (objRect.left + objRect.width) < (tileRect.left + tileRect.width) && (objRect.top + objRect.height) > (tileRect.top + tileRect.height / 2))
hitLeft = (objRect.left + objRect.width) - tileRect.left;
if (objRect.left < (tileRect.left + tileRect.width) && objRect.left > tileRect.left && (objRect.left + objRect.width) >(tileRect.left + tileRect.width) && (objRect.top + objRect.height) >(tileRect.top + tileRect.height / 2))
hitRight = (tileRect.left + tileRect.width) - objRect.left;
if (hitLeft != 0)
tmpSides |= LEFT;
if (hitRight != 0)
tmpSides |= RIGHT;
if (hitTop != 0)
tmpSides |= TOP;
if (hitBottom != 0)
tmpSides |= BOTTOM;
if (sides)
*sides = tmpSides;
If this returns true it calls a hit function that looks something like this:
bool blockedLeft = false,
blockedRight = false;
if (*sides & BOTTOM)
{
position.y = (float)((int)(position.y / tile.height) * tile.height);
blockedBottom = true;
}
if (*sides & TOP && !blockedBottom)
{
position.y = (float)((int)(position.y / tile.height) * tile.height + tile.height);
speed.y = 10;
return;
}
if (*sides & LEFT)
{
position.x = (float)((int)(position.x / tile.width) * tile.width);
blockedRight = true;
}
if (*sides & RIGHT)
{
position.x = (float)((int)(position.x / tile.width) * tile.width + tile.width);
blockedLeft = true;
}
blockedRight = false;
if (*sides & BOTTOM)
{
position.y = (float)((int)(position.y / tile.height) * tile.height);
blockedBottom = true;
}
if (*sides & TOP && !blockedBottom)
{
position.y = (float)((int)(position.y / tile.height) * tile.height + tile.height);
speed.y = 10;
return;
}
if (*sides & LEFT)
{
position.x = (float)((int)(position.x / tile.width) * tile.width);
blockedRight = true;
}
if (*sides & RIGHT)
{
position.x = (float)((int)(position.x / tile.width) * tile.width + tile.width);
blockedLeft = true;
}
Any help would be greatly appreciated.