# Formula for jumping and going down

This topic is 1657 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I can't seem to find any formula for my 2D game. I have a simple sprite and I wan't it to jump up and then go back. It has only to jump up and down, no need for "parabola jump" or anything. I hope you know what I mean.

P.S. I tried something like that, but that didn't work well. It seems that the sprite just teleports up and then teleports back down.

for(int co = 0; co < 50; co++) {
rcSprite.y += 1;
usleep(4000);
}

##### Share on other sites

You gave very little information. However, it seems me that you try to animate the sprite besides the game loop. Timing (and animation is just the timed alteration of variables) is usually driven by the game loop, as well as the rendering is. So, if you alter the rcSprite.y without ever rendering intermediately, you'll see "teleporting".

The usual structure (although it needs some tweaking) is as follows:

In the game loop ...

... iterate until the game is quitted

... ... measure the time that has elapsed since last recent pass

... ... handle user input

... ... update the animated states

... ... perhaps do physics

... ... perhaps do collision handling

... ... render

In the user input section ...

... if the user triggers jumping and rcSprite.jumping == false then set rcSprite.jumping = true

In the update routine of the rcSprite ...

... if rcSprite.delta > 0 and rcSprite.y >= jumpHeight then set rcSprite.delta = -1

... if rcSprite.delta < 0 and rcSprite.y <= groundHeight then set rcSprite.delta = 0, rcSprite.jumping = false, rcSprite.y = groundHeight

... if rcSprite.jumping == true then set rcSprite.y += rcSprite.delta

In the render routine ...
... use current rcSprite.y for rendering
Edited by haegarr

##### Share on other sites

"Parabola jump" is nothing fancy: You jump by changing the velocity of your character vertically by some amount. Every frame, while the character is in the air, you do something like this:

velocity.y += -gravity * delta_time;
position.y += velocity.y * delta_time;

delta_time' is the time elapsed in one frame. You need to detect when you hit the ground so you can stop the jump. You may have to play around with this for a little while to iron out any glitches, but it's very doable.

Edited by Álvaro

##### Share on other sites
//set some forces (vectors with length of resulting force and direction of the force)
Acceleration = result_force / mass;      // a = F / m
//dt is the time between frames

vel = vel + (Acceleration * dt);
pos = pos + (vel * dt);
//now to jump add force to resulting force that has (in example negative direction that gravity force has) but with greater value


##### Share on other sites

I actually made something like that, but in my opinion, that's not the right way to do... Any suggestions/advices? Btw, there's some kind of a bug that when a sprite jumps, it leave all of his colors behind him and when he goes down, same happens... Maybe I should somehow redraw the background (grass) when jumping?

        if ( space ) {
for(int co = 0; co < 50; co++) {
rcSprite.y -= 1;
usleep(500 * co);
SDL_BlitSurface(sprite, &rcSrc, screen, &rcSprite);
SDL_UpdateRect(screen, 0, 0, 0, 0);
}
for(int co = 50; co > 0; co--) {
rcSprite.y += 1;
usleep(300 * co);
SDL_BlitSurface(sprite, &rcSrc, screen, &rcSprite);
SDL_UpdateRect(screen, 0, 0, 0, 0);
}
space = 0;


Edited by arnsa

##### Share on other sites

Doing the entire jump in blocking for loops like that is very bad. Your entire game will halt, no other game logic will be processed and no keys will respond, until the entire jump has been completed. You need to progressively process your jump over several frames like the previous posted have suggested.

##### Share on other sites

Unless you are working on a very underpowered platform (Commodore 64?), you shouldn't have to worry about restoring the background when something moves. You simply redraw the whole screen on every frame.

Search the web for "game loop" to get a more detailed description of how to structure your program.

##### Share on other sites
//set some forces (vectors with length of resulting force and direction of the force)
Acceleration = result_force / mass;      // a = F / m
//dt is the time between frames

vel = vel + (Acceleration * dt);
pos = pos + (vel * dt);
//now to jump add force to resulting force that has (in example negative direction that gravity force has) but with greater value


Maybe that would work, but I don't really know what should be the ratio between the force and the mass aka what numbers should I take for those?

##### Share on other sites

"Parabola jump" is nothing fancy: You jump by changing the velocity of your character vertically by some amount. Every frame, while the character is in the air, you do something like this:

velocity.y += -gravity * delta_time;
position.y += velocity.y * delta_time;

delta_time' is the time elapsed in one frame. You need to detect when you hit the ground so you can stop the jump. You may have to play around with this for a little while to iron out any glitches, but it's very doable.

What do you mean by "time elapsed in one frame"? How do I count it?

##### Share on other sites
You can call SDL_GetTicks at the beginning of the update, compute that and the value you got in the previous iteration and subtract.

There are actually a few problems with that approach, but I think you should start there.

##### Share on other sites

Yeah, you need to work out how your game loop is going to work, but asa others have said, this is the general principle.

Gravity accelerates objects at a constant rate. So you just stick that constant somewhere in your code, and assuming you're using Euler integration*, you just decrease the Y velocity by this amount per tick. To jump, you just set, on a particular tick, the Y velocity to some constant value, which is how hard you can jump.

* If you don't know, then you are probably using Euler integration. Look it up.

Edited by markr

##### Share on other sites

You can call SDL_GetTicks at the beginning of the update, compute that and the value you got in the previous iteration and subtract.

There are actually a few problems with that approach, but I think you should start there.

Now my sprite teleports to the top, if I click jump again, it dissapears and I need to click jump like 4 times so it appears again.

##### Share on other sites

You can call SDL_GetTicks at the beginning of the update, compute that and the value you got in the previous iteration and subtract.

There are actually a few problems with that approach, but I think you should start there.

Now my sprite teleports to the top, if I click jump again, it dissapears and I need to click jump like 4 times so it appears again.

We can't debug your code for you. Step through it with a debugger and see if variables have the values you expect them to have, or dump debugging data on a log file and examine it, to understand what's going on.

To make things simple, use a constant value for delta_time for the time being.

##### Share on other sites

You can call SDL_GetTicks at the beginning of the update, compute that and the value you got in the previous iteration and subtract.

There are actually a few problems with that approach, but I think you should start there.

Now my sprite teleports to the top, if I click jump again, it dissapears and I need to click jump like 4 times so it appears again.

We can't debug your code for you. Step through it with a debugger and see if variables have the values you expect them to have, or dump debugging data on a log file and examine it, to understand what's going on.

To make things simple, use a constant value for delta_time for the time being.

From what I see here, deltaTime really depends on how long I wait before I click jump. I must be doing something wrong...

void handle_event(SDL_Event event, SDL_Rect *rcSrc, SDL_Rect *rcSprite, int *velocity) {
int now = SDL_GetTicks(), delay;
switch(event.type) {
case SDL_QUIT:
gameover = 1;
break;

case SDL_KEYDOWN:
switch(event.key.keysym.sym) {
case SDLK_ESCAPE: case SDLK_q:
gameover = 1;
break;
// some stuff
case SDLK_SPACE:
printf("now: %d, last: %d, delay: %d\n", now, last, now-last);
if (now > last) {
delay = now - last;
last = now;
}
*velocity += (-10) * delay;
rcSprite->y += *velocity * delay;
break;
// some stuff



##### Share on other sites
That doesn't look like you are using a game loop at all.

##### Share on other sites

That doesn't look like you are using a game loop at all.

This function is being called in a game loop.

    while(!gameover) {
if (SDL_PollEvent(&event))
handle_event(event, &rcSrc, &rcSprite, &velocity);

check_sprite_edges(&rcSprite, SPRITE_LION_SIZE);
draw_background(&screen, &sprite_grass, &rcGrass);

SDL_BlitSurface(sprite_lion, &rcSrc, screen, &rcSprite);
SDL_UpdateRect(screen, 0, 0, 0, 0);
}

##### Share on other sites
The updating of velocity and position should be part of the game loop (or, better yet, called from the game loop), because it should happen whether there are events to process or not.

##### Share on other sites

The updating of velocity and position should be part of the game loop (or, better yet, called from the game loop), because it should happen whether there are events to process or not.

Putting it in the main loop didn't change anything.

##### Share on other sites

I guess you don't know how to debug your code. This is a good opportunity for you to learn.

##### Share on other sites

I guess you don't know how to debug your code. This is a good opportunity for you to learn.

Okay, I've found out where the  bug is and now my character's jump depends on gravity and velocity (at last). But here's another problem: it doesn't jump "realistically", it just teleports. If I keep clicking jump, every time it teleports farther. Is this is how it works?

   while(!gameover) {
now = SDL_GetTicks();
if (now > last) {
delay = now - last;
last = now;
}
if(space) {
velocity += (-3) * delay;
rcSprite.y += velocity * delay;
space = 0;
}
if (SDL_PollEvent(&event))
handle_event(event, &rcSrc, &rcSprite, &velocity);
// etc.