Question

I've seen this kinda structure inside the update function in HTML5, Canvas games, with a "modifier" variable:

function update(modifier) {
    obj.x += obj.speed * modifier
    obj.y += obj.speed * modifier
}

function main() {
    var thisLoop = new Date
    var delta = thisLoop - lastLoop
    update(delta / 1000)
    render()
    var lastLoop = new Date
}

var lastLoop = new Date
setInterval(main, 1)

Now I use myself this structure:

function update() {
    obj.x += obj.speed
    obj.y += obj.speed

    render()

    window.requestAnimationFrame(update)
}

What is the "modifier" supposed to do in the first structure?

And which one of them is the best to use, or is there maybe structure with both "modifier" and "requestAnimationFrame" too?

Was it helpful?

Solution

If you need your animation to be locked to time then you need a way to compensate for for example variable frame rates which of course then also have variable time between each frame.

A modifier could (as it's not shown how it is calculated) be used to fine-tune the speed/movement by compensating for this variation.

A couple of things though: don't use such as short time interval (1) as this could have an overall negative effect - you won't be able to update anything faster than the frame rate anyways so use nothing less than 16 ms.

Try to use requestAnimationFrame (rAF) instead as this is the only mechanism able to actually synchronize to the monitor update. rAF also passes a high-resolution timestamp which you can use for the compensator.

For example:

At 60 FPS you would expect a frame to last about 16.67ms.

So a modifier could be set as:

modifier = timeElapsed / 16.67;

If frame was able to run on time the value would be 1 in theory.

modifier = 16.67 / 16.67 = 1;

Now, if a frame iteration for some reason took more time, for example the double, you would get 2 as value for modifier.

modifier = 33.34 / 16.67 = 2;

How does this manifest in practical terms?

If you needed to move 100 pixels per frame then in the first situation when we were on time:

modifier = 16.67 / 16.67 = 1;
vx = 100 * modifier = 100;     // @ 1 frame  = 100 pixels / frame

In the second case we spent two frames which means we needed it to move 200 pixels but since we didn't get that frame in between we need to use the modifier to compensate:

modifier = 33.34 / 16.67 = 2;
vx = 100 * modifier = 200;     // @ 2 frames = 100 pixels / frame

So here you see even if the frame rate was variant we moved what we expected to move anyways.

To calculate time elapsed simply use the rAF argument:

var oldTime = 0                             // old time
    frameTime = 1000 / 60;                  // frame time, based on 60 FPS, in ms

function loop(time) {

    var timeElapsed = time - oldTime;       // get difference
    oldTime = time;                         // store current time as old time

    var modifier = timeElapsed / frameTime; // get modifier based on FPS

    ...

    requestAnimationFrame(loop);
}

Now, all that being said - modifier could also be just a value used to control speed... :-)

OTHER TIPS

The newer version of requestAnimationFrame will return an elapsed time since the animation began.

You can use this elapsed time to determine where your animated objects should be redrawn.

For example, assume you have a ball object with an x property indicating it's x-coordinate.

If you want the ball to move 10 pixels right every 1000ms you can do this (untested!):

// set the starting x-coordinate of the ball

var ballStartingX=50;

ball.x=ballStartingX;

// get the time when the animation is started

var startingTime = performance.now();

// start the animation

requestAnimationFrame(update);

// update() is the animation loop function

function update(timestamp){

    // request another frame

    requestAnimationFrame(update);

    // reposition the ball
    // (timestamp-startTime) is the milliseconds elapsed

    ball.x = ballStartingX + 10 * (timestamp-startTime)/1000;

}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top