Hello there
I'm having quite some trouble with my collision detection,
First off here is my collision detection method
CollisionSide MathsService::RectToRectCollisionName(int rect1_x, int rect1_y, int rect1_w, int rect1_h, int rect2_x, int rect2_y, int rect2_w, int rect2_h)
{
bool collision = false;
// top-left corner
if (PointInRect(rect1_x, rect1_y, rect2_x, rect2_y, rect2_w, rect2_h)){ collision = true; }
// top-right corner
if (PointInRect(rect1_x + rect1_w - 1, rect1_y, rect2_x, rect2_y, rect2_w, rect2_h)){ collision = true; }
// bottom-right corner
if (PointInRect(rect1_x + rect1_w - 1, rect1_y + rect1_h - 1, rect2_x, rect2_y, rect2_w, rect2_h)){ collision = true; }
// bottom-left corner
if (PointInRect(rect1_x, rect1_y + rect1_h - 1, rect2_x, rect2_y, rect2_w, rect2_h)){ collision = true; }
// Check to see if rectangle 2 is hit any part of rectanlge 1
// top-left corner
if (PointInRect(rect2_x, rect2_y, rect1_x, rect1_y, rect1_w, rect1_h)){ collision = true; }
// top-right corner
if (PointInRect(rect2_x + rect2_w - 1, rect2_y, rect1_x, rect1_y, rect1_w, rect1_h)){ collision = true; }
// bottom-right corner
if (PointInRect(rect2_x + rect2_w - 1, rect2_y + rect2_h - 1, rect1_x, rect1_y, rect1_w, rect1_h)){ collision = true; }
// bottom-left corner
if (PointInRect(rect2_x, rect2_y + rect2_h - 1, rect1_x, rect1_y, rect1_w, rect1_h)){ collision = true; }
// If there is no collision
if (collision == true)
{
int rect1xcentre = rect1_x + (rect1_w / 2);
int rect2xcentre = rect2_x + (rect2_w / 2);
int rect1ycentre = rect1_y + (rect1_h / 2);
int rect2ycentre = rect2_y + (rect2_h / 2);
int xDifference = rect1xcentre - rect2xcentre;
int yDifference = rect1ycentre - rect2ycentre;
int xValue = xDifference < 0 ? xDifference * -1 : xDifference;
int yValue = yDifference < 0 ? yDifference * -1 : yDifference;
if (xValue > yValue)
{
CollisionSide result;
xDifference < 0 ? result = CollisionSide::Left : result = CollisionSide::Right;
return result;
}
if (yValue > xValue)
{
CollisionSide result;
yDifference < 0 ? result = CollisionSide::Top : result = CollisionSide::Bottom;
return result;
}
return CollisionSide::None;
}
else
{
return CollisionSide::None;
}
}
This method checks on two rectangles, if they are colliding a side will be return't, however I am getting some odd results.
I have a player which is a 64 by 64 image which can be moving downwards at a total of 16 pixels per tick. Now usually when it hits a block on the floor it will return my enum "Bottom" and the ball will bounce correctly, however now and then the ball get's stuck inside of the block and will go left, right or down. How can I stop this from happening? Do I need to check for a collision 1 tick in front and pre-empt it?
Basically my code to check if the player hits a block is like so
void LevelState::CheckPlayerCollisions()
{
bool collision = false;
for (int i = 0; i < DisplayObjects.size(); i++)
{
if (_mathsService.RectToRectCollision(
DisplayObjects.at(i).XPos,
DisplayObjects.at(i).YPos,
DisplayObjects.at(i).Sprite.getTextureRect().width,
DisplayObjects.at(i).Sprite.getTextureRect().height,
Player.XPos - (Player.Sprite.getTextureRect().width / 2),
Player.YPos - (Player.Sprite.getTextureRect().height / 2),
Player.Sprite.getTextureRect().width,
Player.Sprite.getTextureRect().height
))
{
//Work out the force to bound the ball
CollisionSide result = _mathsService.RectToRectCollisionName(
DisplayObjects.at(i).XPos,
DisplayObjects.at(i).YPos,
DisplayObjects.at(i).Sprite.getTextureRect().width,
DisplayObjects.at(i).Sprite.getTextureRect().height,
Player.XPos - (Player.Sprite.getTextureRect().width / 2),
Player.YPos - (Player.Sprite.getTextureRect().height / 2),
Player.Sprite.getTextureRect().width,
Player.Sprite.getTextureRect().height
);
int force = ceil(Player.YPos / 42);
if (force > 16)
{
force = 16;
}
std::cout << "Force feed back : " << force << std::endl;
Player.HitObjectUpdate(force, result, DisplayObjects.at(i).YPos);
collision = true;
}
if (collision)
{
break;
}
}
}
The method above is being working on of course.
If anyone can give me a hand that would be awesome, I can profile screenshots and pictures if needed.