adamK
adamK

Reputation: 3889

Javascript time-based animation and requestAnimationFrame

I have been playing around with canvas and animation, with HTML5 games in mind specifically and quickly learnt the limitations of just using requestAnimationFrame (rFA) and have moved to time-based animations.

I want to maintain constant gameplay regardless of monitor refresh rate or FPS but am unsure how best to handle the animations. I have read through all sorts of implementations but have not found any best practice so to speak. Should I be using a combination of the two?

So far I have considered several options:

Ignore the lack of browser support and the use of Date.now(), I just want to demonstrate my flow of thinking. I think that the last option is preferable, but the last two can run into problems with updating too far and missing collisions etc as well as updates taking too long that the animation looses all control.

Also when a user tabs out using rFA only the animation will pause, using a time based function to call rFA means that the game/animation will continue to run in the background which is not ideal.

What would be the best way to handle animations trying to keep consistent results regardless of fps, all of the above might be bad and my apologies for the long post (it is just what I have tried so far and am still pretty lost)? even better with with the above issues in mind?

Upvotes: 1

Views: 4336

Answers (3)

Bergi
Bergi

Reputation: 664307

If you have requestAnimationFrame available, I wouldn't go against it and only call draw() from its callbacks. Of course, you should always use delta timing.

Here's a sophisticated variation of raF with a fallback to setTimeout for the game logic updates in case the frame rate is too low:

var maximalUpdateDelay = 25; // ms
var updateTimeout, now;
function animate() {
    updateTimeout = setTimeout(animate, maximalUpdateDelay);
    var delta = -now + (now = Date.now());
    update(now, delta);
}
function main() {
    clearTimeout(updateTimeout);
    animate(); // update the scene
    draw(); // render the scene
    requestAnimationFrame(main);
}
main();

Upvotes: 2

imcg
imcg

Reputation: 2649

I think you're on the right track with the last one because it should give you the most consistency across devices running at different frame rates, but you definitely want to force your delta value down if it gets too high to avoid big jumps:

var animate = function () {
    now = Date.now();
    delta = now - last;
    last = now;

    if(delta > 20) {
        delta = 20;
    }

    draw(delta);
    requestAnimationFrame(animate);
};

Upvotes: 0

zbrunson
zbrunson

Reputation: 1757

I'ld recommend taking a look at the HTML 5 - Game Development course on Udacity. I don't remember the implementation of this problem from the course (but there definitely was one), but my opinion from a gameplay perspective is that just using rAF (like your first bullet) is the most fun, even if there is game slow down due to too much processing needed on slower computers.

Upvotes: 0

Related Questions