Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Which side of my bounding box hit  (Read 823 times)

0 Members and 1 Guest are viewing this topic.

Canvas

  • Full Member
  • ***
  • Posts: 107
    • View Profile
Which side of my bounding box hit
« on: October 20, 2014, 09:45:56 pm »
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.

 

anything