• Advertisement
Sign in to follow this  

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.

If you intended to correct an error in the post then please contact us.

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 this post


Link to post
Share on other sites
Advertisement

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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement