Is there a simple way to make a game loop in JavaScript? something like...
onTimerTick() {
// update game state
}
Is there a simple way to make a game loop in JavaScript? something like...
onTimerTick() {
// update game state
}
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);
});
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...
}