SFML community forums

Help => General => Topic started by: MarbleXeno on July 30, 2020, 07:20:54 pm

Title: Jumping and collision problem
Post by: MarbleXeno on July 30, 2020, 07:20:54 pm
Hello, i'm currently working on a simple game and i have a problem.

There are 2 problems, one that the player can sometimes jump higher, and second that the player can instantly stop at a platform. I kinda know where the problems are, but i don't know how can i fix that.

VIDEO OF THE PROBLEM: problem fixed.

Important variables:
float gravity = 2000.f

Code (only interesting parts)

Part of Player.cpp
void Player::move() {

    //jump
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space) && canJump) {
        jumpAnimation.applyAnimation(50, 0.1f, 100, 0);
        canJump = false;

        playerVelocity.y = -sqrtf(2.0f * gravity * jumpHeight);
    }



    playerVelocity.y += gravity * deltaTime;
    hitbox.move(playerVelocity * deltaTime);
}



void Player::onCollision(sf::Vector2f direction)
{
    if (direction.x < 0.0f) {
        //Collision on left
        playerVelocity.x = 0.0f;

    }
    else if (direction.x > 0.0f) {
        //Collision on right
        playerVelocity.x = 0.0f;

    }

    if (direction.y < 0.0f) {
        //Collision on bottom
        playerVelocity.y = 0.0f;
        canJump = true;
    }
    else if (direction.y > 0.0f) {
        //Collision on top
        playerVelocity.y = 0.0f;
        canJump = false;
    }
}

and part of Collider.cpp
bool Collider::checkCollision(Collider& other, sf::Vector2f& direction, float mass)
{
        sf::Vector2f otherPosition = other.GetPosition();
        sf::Vector2f otherHalfSize = other.GetHalfSize();

        sf::Vector2f thisPosition = GetPosition();
        sf::Vector2f thisHalfSize = GetHalfSize();

        float deltaX = otherPosition.x - thisPosition.x;
        float deltaY = otherPosition.y - thisPosition.y;

        float intersectX = abs(deltaX) - (otherHalfSize.x + thisHalfSize.x);
        float intersectY = abs(deltaY) - (otherHalfSize.y + thisHalfSize.y);

        if (intersectX < 0.0f && intersectY < 0.0f)
        {
                //clamping
                mass = std::min(std::max(mass, 0.0f), 1.0f);

                if (intersectX > intersectY)
                {
                        if (deltaX > 0.0f)
                        {
                                Move(intersectX * (1.0f - mass), 0.0f);
                                other.Move(-intersectX * mass, 0.0f);

                                direction.x = 1.0f;
                                direction.y = 0.0f;
                        }
                        else
                        {
                                Move(-intersectX * (1.0f - mass), 0.0f);
                                other.Move(intersectX * mass, 0.0f);

                                direction.x = -1.0f;
                                direction.y = 0.0f;
                        }
                }
                else
                {
                        if (deltaY > 0.0f)
                        {
                                Move(0.0f, intersectY * (1.0f - mass));
                                other.Move(0.0f, -intersectY * mass);

                                direction.x = 0.0f;
                                direction.y = 1.0f;
                        }
                        else
                        {
                                Move(0.0f, -intersectY * (1.0f - mass));
                                other.Move(0.0f, intersectY * mass);

                                direction.x = 0.0f;
                                direction.y = -1.0f;
                        }
                }

                return true;
        }


        return false;
}
 



Because the code is big i'll explain everything.

Note that in Player.cpp in class onCollision there is a thing that tracks where the player is colliding (top, left, rigth etc.) and when player collides on bottom the playerVelocity.y changes instantly to 0, and thats the problem, i dont know how to fix this, i dont have any idea, so thats beacouse im creating this topic. Thanks for the help :)
Title: Re: Jumping and collision problem
Post by: Stauricus on July 30, 2020, 10:34:11 pm
if the problem is the player jumping higher when he is close to the plataform, i have a guess that it is because he is "stepping" in the plataform for a brief period of time (like 1ms), but it is enough to restart the jumping cycle. you can put some delay to the jumping method, avoiding the player to jump again in the first second, for example.
Title: Re: Jumping and collision problem
Post by: MarbleXeno on July 31, 2020, 12:29:09 am
Okay, thanks, that will work propably, but what can I do with the second problem, (it is in the video too) when player instantly stops at the platform, I have no idea how to fix this.
Title: Re: Jumping and collision problem
Post by: Stauricus on July 31, 2020, 02:36:43 am
i don't understand what is the problem. isn't the plataform supposed to stop the player movement?
Title: Re: Jumping and collision problem
Post by: MarbleXeno on July 31, 2020, 11:09:36 am
Second issue: the player immediately stops on the Y axis when collides.
It can be seen on the video at this moment: https://youtu.be/q22JX7iyhPc?t=59
Title: Re: Jumping and collision problem
Post by: Arcade on July 31, 2020, 04:26:36 pm
A possible fix for both of your issues could be to tweak your collision response to something like this

if (direction.y < 0.0f && playerVelocity.y <= 0.0f) {
        //Collision on bottom
        playerVelocity.y = 0.0f;
        canJump = true;
    }
 

That way the player can't land on the platform if they are still in the upward part of their jump. I'm assuming a negative velocity in your code means the player is moving down, but you can of course flip the comparison if it's the opposite.
Title: Re: Jumping and collision problem
Post by: MarbleXeno on July 31, 2020, 09:10:44 pm
Thank you very much! This worked. SFML has a really great community!