0
\$\begingroup\$

I've been working on a game in javascript/html5 (through typescript) using my own little library. This library uses a variable timestep since I plan on using it on mobile devices, and I was under the assumption that this will help keep things roughly the same on both (I know there's probably a debate on that, but that's not what I'm asking).

The problem is, using my variable timestep, I'm getting wildly different entity speeds. I am working out how long in seconds the frame took to update and draw, then multiplying entity velocities by this.

I'm running the game loop using setInterval. It's set up to run at 60fps, so a 16(ish)ms interval.

var now: Date = new Date();
timeInterval = (now.getTime() - Engine.lastUpdate.getTime()) / 1000;
Engine.lastUpdate = now;
Input.update();
currentScene.update();            
draw();

Player class:

        update() {

        //W:87 S:83 A:65 D:68

        this.velocity.y += this.gravity;

        if (SandLib.Input.isKeyJustDown(16)) {
            this.gravity *= -1;
            this.jumpPow *= -1;
        }

        this.velocity.x += this.accel;

        if (this.velocity.x > this.maxVel) {
            this.velocity.x -= this.decel;
        }

        if (this.x > this.cameraMoveZone) {
            SandLib.Engine.currentScene.camera.x = this.x - this.cameraMoveZone;
        }

        //Collision code here

        if (SandLib.Input.isKeyJustDown(32) && this.onGround) {
            this.velocity.y -= this.jumpPow;
            this.velocity.x *= this.jumpBoost;
            this.onGround = false;
            Main.jumpSnd.play();
        }

        if (this.y > 800 || this.y < -800) {
            this.die();
        }            
        super.update();
    }

Any ideas why this gives a faster speed on lower fps devices.

\$\endgroup\$
1

2 Answers 2

1
\$\begingroup\$

It's possible that there's a bug in your delta time calculation or a bug in your calculations for entity movement. It's hard to say without seeing more code, but I don't think you need to divide the delta time by 1000. That value should already be in milliseconds. Your movement code should then multiply the entity's speed per millisecond by the number of milliseconds since last frame, which should generally be ~16.

// entity.speed is something like 0.25, deltaTime is ~16
// entity moves 4 pixels this frame
entity.x += (entity.speed * deltaTime);

Either way, you should be using requestAnimationFrame instead of setInterval as explained by Paul Irish. Also, checkout this update for sub-millisecond precision.

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

So, you calculate timeInterval, and then don't use that value for anything? At least that is what is visible in the code shown. If you want to use variable time step then you have got to multiply with the timeInterval in every integration step.

this.velocity.y += this.gravity * timeInterval;
this.velocity.x += this.accel * timeInterval;
this.velocity.x -= this.decel * timeInterval;

And I guess there is more of them outside of the shown code.

But really, fix your time step, it works great, but it is also the easy thing to do. A few lines of code to keep the timing, and the entire rest of your application can be written with no specific consideration for time.

\$\endgroup\$
2
  • \$\begingroup\$ "But really, fix your time step" : Meaning that 20 fps, 30 fps and 50 fps devices (and others) are not that important ?? Or that doing computation multiplying by the real time elapsed is too complicated ?? \$\endgroup\$ May 7, 2013 at 11:14
  • \$\begingroup\$ @VincentPiel Meaning that a load of possible issues will be avoided, including a lot of possible screw ups for people who are not that much into the mathematical aspect of variable time step. 120 Hz time step is usually recommended as it makes a nice 2 steps per frame for 60 Hz screens, but is sufficiently high that other refresh rates should look pretty good as well. \$\endgroup\$ May 7, 2013 at 14:00

You must log in to answer this question.

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