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

Author Topic: Collision detection not working vertically (approx.) halfway across the window  (Read 1419 times)

0 Members and 1 Guest are viewing this topic.

Miimoo

  • Newbie
  • *
  • Posts: 2
    • View Profile
Hi guys,

I'm fairly new to SFML programming and only have about half a year (give or take) experience in C++ programming (self taught).

I'm trying to make a simple platformer that involves moving a box that can jump on top of other boxes. I'm also using a fixed time step, based off the code from the textbook "SFML Game Development By Example".

The problem is that when I place the boxes to be jumped on at a vertical location >= 300, collision is detected and the player box lands perfectly. But anything <= 300, collision is not detected.

Any help or advice would be greatly appreciated :)
 
Here is my code for the game logic (sorry if it's messy or poorly written):

 Game::Game() : window(sf::Vector2u(640,480), "Title"), player(window), one(window), two(window.GetWindow()->getSize().x/2, window.GetWindow()->getSize().y-120)
{
        isDone = false;
       
        size = sf::Vector2u(640, 480);
        three.SetPosition(100, 300);


}


bool Game::Collision(Player& p, Obstacle& o)
{
       
        if (p.Bot() == o.Top() && p.Right() >= o.Left() && p.Left() <= o.Right())
        {
                std::cout << "Colliding\n";
                return true;

        }

        else
                return false;
}



void Game::Render()
{
        window.Clear();
        window.Draw(*player.GetPlayer());
        window.Draw(*one.GetObstacle());
        window.Draw(*two.GetObstacle());
        window.Draw(*three.GetObstacle());
       
        window.Display();
}

void Game::RestartClock()
{
        elapsed += clock.restart();
}



void Game::Update()
{
        float frametime = 1.0f / 60.0f;
       


        if (elapsed.asSeconds() >= frametime)
        {
       

                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
                {
                        player.MoveRight();
                }

                else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
                {
                        player.MoveLeft();
                }



                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space))
                {
                        player.Jump();
                        player.setJumping(true);
                }

       
                //if player bottom isn't touching bottom of screen
                if (player.GetPlayer()->getPosition().y + player.GetPlayer()->getSize().y != window.GetWindow()->getSize().y)
                {
                       
                        //logic to handle jumping on boxes
                        if (Collision(player, one) || Collision(player,two) || Collision(player,three))
                        {
                                //std::cout << "Stay\n";
                        }
                        else
                        {
                               
                                player.Gravity();
                       
                        }
                }

       
               

                elapsed -= sf::seconds(frametime);
        }

        sf::Event e;
        while (window.GetWindow()->pollEvent(e))
        {
                switch (e.type)
                {
                case::sf::Event::Closed:
                        isDone = true;
                        window.GetWindow()->close();
                        break;

                case::sf::Event::KeyReleased:
                        if (e.key.code == sf::Keyboard::Space)
                        {
                                player.setJumping(false);
                                std::cout << "Release\n";
                        }
                        break;

                default:
                        break;
                }
        }
               
}

bool Game::IsDone()
{
        return isDone;
}




//OBSTACLE CLASS

Obstacle::Obstacle(WindowType& window)
{
        w_size = window.GetWindow()->getSize();
        rect.setSize(sf::Vector2f(80, 5));
        rect.setFillColor(sf::Color::Blue);
       
        rect.setPosition(w_size.x - 140, w_size.y - 60);
}

Obstacle::Obstacle(float x, float y)
{
       
        rect.setSize(sf::Vector2f(80, 5));
        rect.setFillColor(sf::Color::Red);
        rect.setPosition(x, y);

}

Obstacle::Obstacle(sf::Vector2f p_size)
{
        w_size_f = p_size;
        rect.setSize(sf::Vector2f(80, 5));
        rect.setFillColor(sf::Color::Red);

}

Obstacle::Obstacle() //creates obstacle of random size
{
        //code to randomly set size
        /*
        srand(time(0));
        int sizeX = (rand() % 50) + 50;
        int sizeY = (rand() % 5) + 1;
        rect.setSize(sf::Vector2f(static_cast<int>(sizeX), static_cast<int>(sizeY)));
        */

        rect.setSize(sf::Vector2f(80, 5));
        rect.setFillColor(sf::Color::White);
}



void Obstacle::SetPosition(int x, int y)
{
       
        rect.setPosition(x, y);
}

void Obstacle::RandPosition()
{
        //randomly creates a position for the rectangle
        srand(time(0));
        int randX, randY;
        int randR, randG, randB;

        randX = rand() % static_cast<int>(w_size_f.x - rect.getSize().x) + 1;
        randY = rand() % static_cast<int>(w_size_f.y - rect.getSize().y) + 1;
        rect.setPosition(randX, randY);
}

int Obstacle::Right()
{
        int right = rect.getPosition().x + rect.getSize().x;
        return right;
}

int Obstacle::Left()
{
        int left = rect.getPosition().x;
        return left;
}

int Obstacle::Top()
{
        int top = rect.getPosition().y;
        return top;
}

int Obstacle::Bot()
{
        return rect.getPosition().y + rect.getSize().y;
}

sf::RectangleShape* Obstacle::GetObstacle()
{
        return &rect;
}



//PLAYER CLASS

Player::Player(WindowType& win)
{
        w_size = win.GetWindow()->getSize();
        rect.setFillColor(sf::Color::Green);
        //rect.setOrigin(rect.getSize().x / 2, rect.getSize().y / 2);
        rect.setSize(sf::Vector2f(50, 50));
        rect.setPosition(w_size.x / 2, w_size.y - rect.getSize().y);
        isJumping = false;
        movespeed = 5.0f;
        jumpspeed = -20.0f;
        gravity = 4.0f;
}

int Player::Right()
{
        int right;
        right = rect.getPosition().x + rect.getSize().x;
        return right;
}

int Player::Left()
{
        int left;
        left = rect.getPosition().x;
        return left;
}

int Player::Bot()
{
        int bot = rect.getPosition().y + rect.getSize().y;
        return bot;
}

int Player::Top()
{
        int top = rect.getPosition().y;
        return top;
}

void Player::Move(int x, int y)
{
        rect.setPosition(rect.getPosition().x + x, rect.getPosition().y + y);
}

void Player::MoveLeft()
{
        Move(-movespeed, 0);
}

void Player::MoveRight()
{
        Move(movespeed, 0);
}

void Player::Jump()
{
        Move(0, jumpspeed);
}

void Player::Gravity()
{
        Move(0, gravity);
}

bool Player::IsJumping()
{
        return isJumping;
}

void Player::setJumping(bool b)
{
        isJumping = b;
}

sf::RectangleShape* Player::GetPlayer()
{
        return &rect;
}
« Last Edit: October 03, 2017, 10:01:29 am by Laurent »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Quote
p.Bot() == o.Top()
This could never be true. Although Bot() and Top() return integers, if the player moves by more than a single pixel between two collisionc checks, then he might skip the obstacle bottom and go through it.

You should find a more robust way to check collisions.

Also, don't hesitate to debug your program, print (or inspect with the debugger) what happens, etc. In this case it's really easy to see what's going on by printing the successive positions of the player bottom.
Laurent Gomila - SFML developer

Miimoo

  • Newbie
  • *
  • Posts: 2
    • View Profile
Quote
In this case it's really easy to see what's going on by printing the successive positions of the player bottom.
Hi, after following your advice, I was able to fix the problem.
 
Thank you for your help! :)