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

Author Topic: [SOLVED]Collision Detection Bug  (Read 1492 times)

0 Members and 2 Guests are viewing this topic.

Wnt2bsleepin

  • Guest
[SOLVED]Collision Detection Bug
« on: May 12, 2013, 12:04:10 am »
I have a side scrolling tile based game, and I am having a bug with the collision detection on tiles. It works for the most part, but there is one bug which I can't figure out how to solve.

When a player moves and hits a wall, if they try to move in the opposite direction, they end up going through the wall.






I am not too sure how to handle it.

Here is the collision detection code:

if(level_One->checkCollision(player1->playerSprite)){
        sf::Vector2<float> speed;
        speed.y = playerSpeed.y;
        if(key == sf::Keyboard::Right){
           speed.x  = -2.0f;
           player1->updatePlayer(speed);
        }
        else if(key == sf::Keyboard::Left){
           speed.x = 2.0f;
           player1->updatePlayer(speed);
        }
    }

bool level::checkCollision(sf::Sprite &playerSprite){
    for(int i = 0; i < mapHeight; i++){
                for(int j = 0; j < mapWidth; j++){
            sf::Rect<float> playerBounds = playerSprite.getGlobalBounds();
            playerBounds.height -= 20;
            sf::Rect<float> tileBounds = mapSprites[i][j].sprite->getGlobalBounds();
            if(playerBounds.intersects(tileBounds) && !mapSprites[i][j].passThrough){
                return true;
            }
        }
    }
   
    return false;
}

Any help is appreciated.
« Last Edit: May 12, 2013, 01:07:39 am by Wnt2bsleepin »

The Terminator

  • Full Member
  • ***
  • Posts: 224
  • Windows and Mac C++ Developer
    • View Profile
Re: Collision Detection Bug
« Reply #1 on: May 12, 2013, 12:39:40 am »
Can you post the implementation for updatePlayer(sf::Vector2f)?
Current Projects:
Technoport

Wnt2bsleepin

  • Guest
Re: Collision Detection Bug
« Reply #2 on: May 12, 2013, 01:04:33 am »
I believe I may have solved it.

1) The player moves right until he hits something. The game sets the player's velocity to  be the reverse of the direction of movement, away from the tile.

2) This causes you to move a little bit away from the tile, but not far enough away to trigger the collision detection.

3) As long as the user get pressing the Right key, they wouldn't go through the wall but would be continuously put back to the position right before it.

4) If the user decided to press the Left button, the collision detection would still trigger even though there was nothing behind the sprite and the tile causing the issue is the one in front.

5) The player would then move in the opposite direction of the (wrong) obstructing tile, which in this case is towards the actual blocking tile. This bypassing the collision detection.


My solution was to simulate their movements again inside of the collision check

   if(level_One->checkCollision(player1->playerSprite)){
        //level::Tile tile= level_One->GetTile(player1->playerSprite);
        sf::Vector2<float> speed;
        speed.y = playerSpeed.y;
        if(key == sf::Keyboard::Right){
            speed.x  = -1.0f;
            sf::Sprite temp = player1->playerSprite;
            temp.setPosition(player1->getPosition().x - 1.0f, player1->getPosition().y);
            if(!level_One->checkCollision(temp)){
                player1->updatePlayer(speed);
            }
            else{
                speed.x = 1.0f;
                player1->updatePlayer(speed);
            }
        }
        else if(key == sf::Keyboard::Left){
            speed.x = 1.0f;
            sf::Sprite temp = player1->playerSprite;
            temp.setPosition(player1->getPosition().x + 1.0f, player1->getPosition().y);
            if(!level_One->checkCollision(temp)){
                player1->updatePlayer(speed);
            }
            else{
                speed.x = -1.0f;
                player1->updatePlayer(speed);
            }
        }
       
        else{
            player1->updatePlayer(speed);
        }
    }


This seems to work.


updatePlayer
void Player::updatePlayer(sf::Vector2<float> position){
    //Eventually add damage and health modifications here.
    //playerSprite.setPosition(position.x, position.y);
    playerSprite.move(position.x, position.y);
}

The Terminator

  • Full Member
  • ***
  • Posts: 224
  • Windows and Mac C++ Developer
    • View Profile
Re: [SOLVED]Collision Detection Bug
« Reply #3 on: May 12, 2013, 01:59:25 am »
Well, glad you worked it out. Post again if you have any other troubles :)
Current Projects:
Technoport

 

anything