1
\$\begingroup\$

I am making a Java game and I want my game to run the same on any FPS so I'm using time delta between each update. This is the update method of the Player:

    public void update(long timeDelta) {

        //speed is the movement speed of a player on X axis
        //timeDelta is expressed in nano seconds so I'm dividing it with 1000000000 to express it in seconds

        if (Input.keyDown(37))
            this.velocityX -= speed * (timeDelta / 1000000000.0);

        if (Input.keyDown(39))
            this.velocityX += speed * (timeDelta / 1000000000.0);

        if(Input.keyPressed(38)) {
            this.velocityY -= 6;
        }

        velocityY += g * (timeDelta/1000000000.0); //applying gravity
        move(velocityX, velocityY); /*this is method which moves a player 
                                        according to velocityX and velocityY, 
                                        and checking the collision
                                    */

        this.velocityX = 0.0;
    }

The strange thing is that when I have unlimited FPS (and update number) my player is jumping about 10 blocks. It jumps even higher when the FPS is increasing. If I limit FPS it is jumping 4 blocks. (BLOCK: 32x32) I have just realized that the problem is this:

if(Input.keyPressed(38)) {
    this.velocityY -= 6;
}

I add -6 to velocityY which increases player's Y proportionally to the update number and not to the time.

But I don't know how to fix this.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ For the love of $DEITY, don't repeat timeDelta / 1000000000.0 all over the place. Compute that once when calculating your delta and just pass that through everywhere. Don't repeat yourself, don't perform unnecessary computations, and don't sprinkle your code with magic numbers. \$\endgroup\$ Sep 23, 2013 at 18:28
  • 1
    \$\begingroup\$ The correct term is not speed but acceleration. By naming your variables correctly, it will make things less confusing. \$\endgroup\$ Oct 24, 2013 at 7:07

2 Answers 2

1
\$\begingroup\$

You should add a jumpAcceleration. When the player press key(38) you should do

this.velocityY -= jumpAcceleration * dt;

where dt is timeDelta / 1000000000.0 .
What you do in your code is, you add 6 to the velocityY at every update. So at high FPS (e.x. 300 ) you will subtract 6 * 300 = 1800 from your velocityY, but at a low FPS (e.x. 10 ) you will subtract 60 from your velocityY, at every second. If you want to make your game independent of the FPS you have to add timeDelta there too.

Also search at google for game loops. There is information on how to create a solid and FPS independent game loop for your game.

\$\endgroup\$
0
\$\begingroup\$

Simple solution: Only add the jumping speed if you're actually on the ground and/or standing still.

Something like this:

if (Input.keyPressed(38) && onGround)
    this.velocityY -= 6;

The actual check could be more complicated. For example rather than using a boolean value you could use some counter canJump that is by default set to 1 or 2 whenever you're on solid ground. If you try to jump (key pushed down; not just held down!) and the counter is bigger than 0 you apply the velocity and reduce the counter. This way it's rather easy to implement things like double jumps or even triple jumps.

\$\endgroup\$
4
  • \$\begingroup\$ This is the thing I will implement after I fix my problem described in my question. This is useful, but it doesn't answer my question. \$\endgroup\$
    – Luka Tiger
    Sep 23, 2013 at 19:44
  • \$\begingroup\$ It should fix your problem, because once you're in the air onGround will no longer be true (i.e. no more velocity added). This should only fire once (right now it fires as long as you keep the button pressed). \$\endgroup\$
    – Mario
    Sep 23, 2013 at 20:05
  • \$\begingroup\$ keyPressed() returns true if the key is pressed right now (in this update cycle) and keyDown() returns true if the key is down. So, it won't fix my problem. The problem is that I add -6 on velocityY and I increase my Y according to velocityY each update so if I increase FPS it will increase Y proportionally to update number but it actually have to be proportionally to time. But I don't know how to fix that. \$\endgroup\$
    – Luka Tiger
    Sep 23, 2013 at 20:35
  • \$\begingroup\$ Correct, exactly how I expected this to work. You just have to ensure you don't add the velocity unless you're on the ground somehow (as written in my answer). How you detect this is up to you (e.g. determine whether there is something solid right under your feet). \$\endgroup\$
    – Mario
    Sep 24, 2013 at 9:32

You must log in to answer this question.

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