2
\$\begingroup\$

So, I ask question about my 2D game, actually it is not game, but it is something like poor game. Well i made moving system and now is time to make jump. I made some kind of gravity with tutorial but I don't like it. It is simple and nice but there is problems in that gravity example: 1. You can hold up arrow and "fly" with jump. I tried to fix that and make some kind of limit to jump but it was bad try. Second problem is that when you jump and you release up arrow (jumping key) then my sprite fall very fast and I can't really control that sprite in air.

This is my first game and I want spend time to do that, but now i have problem that i can't solve with my self so if you can help, please do it. I use C++ with CodeBlocks and SFML multimedia library.

So there is little parts of my code.

First there is velocity and gravity configuration:

     //gravity & velocity
     const float gravity = 1;
     int ground = 600; //height of ground
     Vector2f velocity(Vector2f(0,0));
     float movingSpeed = 0.5f, jumpingSpeed = 2.0f;

Then there is simple when you press button you jump:

if(Keyboard::isKeyPressed(Keyboard::Up)){
            skeleton.move(0,velocity.y = -jumpingSpeed);
            source.y = Up;
            isWalking = true;
        }

And there is system what recognize if you jump and this make you fall:

if(skeleton.getPosition().y + skeleton.getScale().y < ground || velocity.y < 0){
             velocity.y += gravity;
        }else{
            skeleton.setPosition(skeleton.getPosition().x, ground - skeleton.getScale().y);
        }

So my sprite name is "skeleton". And yeah this is first time with game physics. I'm not very good game programmer so these code can be poor and yeah... if you invent a solution share it.

\$\endgroup\$
1
  • 2
    \$\begingroup\$ 1) The 'jump' impulse should be given only on a "is Just Pressed" event, not on a "is Pressed", and 2) Once the impulse is given, a flag should be set indicating that the character is in the air: the "is Just Pressed" event should not trigger the jump until that flag is reset (it is resent when the character touches the ground). \$\endgroup\$
    – Vaillancourt
    Commented May 13, 2016 at 13:46

1 Answer 1

2
\$\begingroup\$

Here's one of my go-to jump functions. It's similar to a Mario jump - fast at first, slowing down until reaching the top.

Please excuse the syntax. I haven't used C++ in ages, and never SFML.

const float GRAVITY = 9.0f;
const float MAX_VELOCITY = -10.0f;
const float MAX_AIR_TIME = 1.2f;

float timeInAir = 0.0f;
float jumpImpulseTime = 0.2f;
float jumpImpulseVel = -10.0f; 
float jumpAccel = -1.0f;


void doJump () {
    Vector2f accel = new Vector2f(0.0, 0.0);
    Vector2f vel = new Vector2f(0.0, 0.0);

    // Allow player to jump
    if (isTouchingGround) {
        timeInAir = 0.0f;
        accel.y = 0.0;
        vel.y = 0.0;
    }

    // Handle vertical velocity and acceleration
    if (Keyboard::isKeyPressed(Keyboard::Up)) {
        // First, jump up quickly..
        if (timeInAir < jumpImpulseTime) {
            vel.y = jumpImpulseVel;
        }
        // Then slowly go higher.. 
        else if (timeInAir < MAX_AIR_TIME) {
            acc.y = jumpAccel;
        }
        // Until finally falling
        else {
            acc.y = GRAVITY;
        }
    }
    else {
        // Prevent double jumps
        timeInAir = MAX_AIR_TIME;
        acc.y = GRAVITY;
    }

    player.velocity.y = vel.y;
    player.acceleration.y = accel.y;
}

void update(float deltaTime) {
    doMove();
    doJump();

    player.velocity = player.velocity + (player.acceleration * deltaTime);

    // Clamp to maximum velocity
    player.velocity.x = math.min(MAX_VELOCITY, math.max(player.velocity.x, -MAX_VELOCITY));
    player.velocity.y = math.min(MAX_VELOCITY, math.max(player.velocity.y, -MAX_VELOCITY));
}
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .