My collision detection method is solid and detects box to box collision every time. Then comes the resolve part which I'm struggling with quite a bit. It works perfectly when I'm manipulating the x-axis and y-axis of the player (tile) but only happens to work when I move on any given axis individually. If I try to move on both axis then the whole thing breaks down and starts acting weird.
I'm trying to implement gravity. And so I keep a constant down force on my player tile. This is when I realized that when I'm applying force on both axis (because gravity is constantly applying force on the y-axis) and moving the player tile right or left on the same time my collision resolve method breaks down.
My collision is working great while moving along each axis individually. Here's the result:
How can I approach collision resolution in order to avoid this type of result?
I'm currently predicting the position the player will be at, then I'm checking every single collideable tile at that position. If I detect a collision, I move the player back along the axis the collision was detected in.
This is my current code with collisions working well on a single axis at a time:
void Tile_Player::Move(double delta, G3::Tile_Map *map)
{
int xvel = (this->xDirection * (G3::TILE_STEP * (delta/1000)));
int yvel = (this->yDirection * (G3::TILE_STEP * (delta/1000)));
G3::xy_pos predictedPos;
predictedPos.x = this->tile_location.x; predictedPos.y = this->tile_location.y;
predictedPos.x += xvel;
predictedPos.y += yvel;
bool collision_status = false;
for (int i=0; i< map->GetTotalTileCount(); i++)
{
G3::Tile *tempTile = map->GetTileAt(i);
if (this != tempTile)
{
bool coll_bool;
coll_bool = this->CheckCollision(predictedPos, tempTile->GetTilePos());
if (coll_bool)
{
//check collision on the left
if (this->xDirection == -1)
{
predictedPos.x = tempTile->GetTilePos().x+G3::TILE_SIZE+0.1;
}
//check collision on the right
if (this->xDirection == 1)
{
predictedPos.x = tempTile->GetTilePos().x-G3::TILE_SIZE-0.1;
}
//check collision on bottom(ground)
if (this->yDirection == -1)
{
predictedPos.y = tempTile->GetTilePos().y+G3::TILE_SIZE+0.1;
}
//check collision on top
if (this->yDirection == 1)
{
predictedPos.y = tempTile->GetTilePos().y-G3::TILE_SIZE-0.1;
}
}
}
}
this->tile_location.x = predictedPos.x;
this->tile_location.y = predictedPos.y;
this->xDirection = 0;
this->yDirection = 0;
}