Best way for simple game-loop in Javascript?

Viewed 41053

Is there a simple way to make a game loop in JavaScript? something like...

onTimerTick() {
  // update game state
}
7 Answers
setInterval(onTimerTick, 33); // 33 milliseconds = ~ 30 frames per sec

function onTimerTick() {
    // Do stuff.
}

Many of these answers are outdated and suboptimal. The recommended way to do this now is using requestAnimationFrame.

For example:

let previousTime = 0.0;

const loop = time => {
  // Compute the delta-time against the previous time
  const dt = time - previousTime;

  // Update the previous time
  previousTime = time;

  // Update your game
  update(dt);

  // Render your game
  render();

  // Repeat
  window.requestAnimationFrame(loop);
};

// Launch
window.requestAnimationFrame(time => {
  previousTime = time;

  window.requestAnimationFrame(loop);
});

Fixed time-step

If you want to achieve a fixed time-step, simply accumulate delta-time until it reaches some threshold, then update your game.

const timeStep = 1.0 / 60.0;

let previousTime = 0.0;
let delta = 0.0;

const loop = time => {
  // Compute the delta-time against the previous time
  const dt = time - previousTime;

  // Accumulate delta time
  delta = delta + dt;

  // Update the previous time
  previousTime = time;

  // Update your game
  while (delta > timeStep) {
    update(timeStep);

    delta = delta - timeStep;
  }

  // Render your game
  render();

  // Repeat
  window.requestAnimationFrame(loop);
};

// Launch
window.requestAnimationFrame(time => {
  previousTime = time;

  window.requestAnimationFrame(loop);
});

Yep. You want setInterval:

function myMainLoop () {
  // do stuff...
}
setInterval(myMainLoop, 30);

Would this do?

setInterval(updateGameState, 1000 / 25);

Where 25 is your desired FPS. You could also put there the amount of milliseconds between frames, which at 25 fps would be 40ms (1000 / 25 = 40).

not sure how well this will work, but here is one method that uses a while loop and sleeps the thread. This is just an example, you can replace the game loop below with a better one, based on how you would do it in any other language. You can also find a better while loop here

let gameRunning = false;

async function runGameThread(){
    if(!gameRunning){
        gameRunning = true;

        // this function allows the thread to sleep (found this a long time ago on an old stack overflow post)
        const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));

        // the game loop
        while(gameRunning){
            let start = new Date().getTime();
            gameUpdate();
            await sleep(start + 20 - new Date().getTime());
        }

    }
}

function stopGameThread(){
    while(gameRunning){
        try{
            gameRunning = false;
        }catch(e){}
    }
}

function gameUpdate(){
    // do stuff...
}
Related