Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript game loop that runs at the same speed?

I have a javascript game that will run really fast on some computers and really slow on others. I've been doing some research and I've found that I need to update my loop based on time, but I can't seem to find any good examples of this for javascript. Can someone point me to the right direction on how to get a game to run at 30fps on any hardware?

Thanks

like image 669
Dave Avatar asked Aug 25 '11 15:08

Dave


4 Answers

Normally games work from a Delta Time, that is, the amount of time since the last frame was rendered.

Psuedocode (roughly C#):

DateTime lastFrameTimeStamp = DateTime.Now;
void Draw()
{
    TimeSpan timeSinceLastFrame = DateTime.Now.Subtract(lastFrameTimeStamp);
    float deltaTime = timeSinceLastFrame.TotalSeconds;

    // Do all of your movement and other time-based math based on the deltaTime, Like:
    float x = x + (MovementPerSecond * deltaTime);


    lastFrameTimeStamp = DateTime.Now;
}

Using a Delta Time prevents all dependency on CPU power or how often frames get drawn.

like image 121
John McDonald Avatar answered Nov 19 '22 04:11

John McDonald


You can't force a game to run at 30fps if the hardware is unable achieve it. If what it is doing is taking more than 1/30th of a second, you're out of luck.

You can use requestAnimationFrame to let it run as fast as it can though. See here: http://paulirish.com/2011/requestanimationframe-for-smart-animating/

like image 27
Simon Sarris Avatar answered Nov 19 '22 05:11

Simon Sarris


You could have a timer function which you can measure how long you are executing for, then call back to yourself at your ((required interval) - (execution time)), in pseudo code

function timer(){
    var timeStart = new Date();
    // Your stuff
    setTimeout (timer, (1000/30) - (new Date() - timeStart));
}
like image 1
tonycoupland Avatar answered Nov 19 '22 05:11

tonycoupland


What you are looking for is a simple implementation of delta timing in JavaScript. Implememting it in JavaScript is a relatively simple task. In fact it's so simple that it can be achieved in less than 25 lines of code (stripping out blank lines and comments):

function DeltaTimer(render, interval) {
    var timeout;
    var lastTime;

    this.start = start;
    this.stop = stop;

    function start() {
        timeout = setTimeout(loop, 0);
        lastTime = Date.now();
        return lastTime;
    }

    function stop() {
        clearTimeout(timeout);
        return lastTime;
    }

    function loop() {
        var thisTime = Date.now();
        var deltaTime = thisTime - lastTime;
        var delay = Math.max(interval - deltaTime, 0);
        timeout = setTimeout(loop, delay);
        lastTime = thisTime + delay;
        render(thisTime);
    }
}

Using it is even more simple. Let's learn by example:

var timer = new DeltaTimer(render, 1000 / 30);
var start = timer.start();
var body = document.body;
var frame = 0;

function render(time) {
    time -= start;
    body.innerHTML += (frame++) + ". " + time + " ms<br/>";

    if (time >= 1000) {
        var stop = timer.stop() - start;
        body.innerHTML += "<br/>" + stop + " ms (stopped)";
    }
}

I think the code is pretty self explanatory. For the live demo click on this link.

like image 1
Aadit M Shah Avatar answered Nov 19 '22 06:11

Aadit M Shah