One thing you should always remember about using setInterval: if we set number of milliseconds at - let’s say 20ms - it will call our game loop function EACH 20ms, even if the previous one is not yet finished. This may lead to many problems (incomplete rendering, etc.).
That's where we can use another function:
setTimeout(function, ms);
This function works like setInterval(...) with one difference: it calls your function ONCE and AFTER a given amount of time.
Check the example below (click on start animation):
This is similar to the previous example except that we called setTimeout(function, delay) instead of setInterval(function, period). As setTimeout runs the function passed as the first parameter only once, we also have to call it at the end of the loop.
Extract from source code:
function animationLoop() {
// 1 - Clear
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 2 Draw
drawMonster(monsterX, monsterY, monsterAngle, 'green', 'yellow');
// 3 Move
monsterX += 10;
monsterX %= canvas.width
monsterAngle+= 0.01;
// call mainloop again after 20ms
requestId = setTimeout(animationLoop, 20);
}
function start() {
// Start the animation loop, change 20 for bigger
// values
requestId = setTimeout(animationLoop, 20);
}
function stop() {
if (requestId) {
clearTimeout(requestId);
}
}
This function is certainly more suitable for doing graphic animation, such as for writing an HTML5 game. It will never interrupt an ongoing animation, even if the instructions inside the animation loop take too long.
setTimeout does not "wait" during the timeout period. It lets the rest of the JavaScript code run. It schedules a new call to the function passed as first parameter with a timer running in the background. This might cause it to take slightly longer than the expected timeout period to start executing.
This problem also occurs with setInterval, the timing is not "very" reliable. If you plan to run a function every 20ms, and if you measure precisely the real timing, sometimes you will discover big differences between what is scheduled and what is performed. This is because these methods were designed a long time ago, when high precision timers and 60 frames per second animation were not an option.
Here comes the requestAnimationFrame API, a very good companion to the canvas API!