Copyright Derek O'Reilly, Dundalk Institute of Technology (DkIT), Dundalk, Co. Louth, Ireland.
Timers can be used to call a javascript function at set intervals. There are two ways to call a timer function:
A timer that has been set by setInterval() can be stopped by calling:
In order to use clearInterval(), a timer variable needs to be associated with a call to setInterval. This is done below:
let myTimer = setInterval(myFunction, 100); clearInterval(myTimer);
Example using setInterval (Run Example)
<!-- Author: Derek O Reilly, Dundalk Institute of Technology, Ireland. --> <!DOCTYPE html> <html> <head> <title>Course notes example code</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> #gameCanvas { /* the canvas styling usually does not change */ outline:1px solid darkgrey; width:500px; height:500px; } </style> </head> <body> <canvas id = "gameCanvas"></canvas> <script> let mapImage = new Image(); mapImage.src = "images/map.png"; let carImage = new Image(); carImage.src = "images/car.png"; window.onload = function () { let canvas = document.getElementById("gameCanvas"); canvas.width = canvas.clientWidth; canvas.height = canvas.clientHeight; let ctx = canvas.getContext("2d"); let x = 0; animationInterval = setInterval(renderCanvas, 25); // call renderCanvas function every 25 milliseconds function renderCanvas() { ctx.drawImage(mapImage, 0, 0, canvas.width, canvas.height); // clear any previous drawing if (x > (canvas.width + 1)) { x = 0; } else { ctx.drawImage(carImage, x, 240, 40, 20); x++; } } }; </script> </body> </html>
In the above example, the rendering code is tied to the moving image (gameObject) code. This solution is fine when there is only one gameObject. It is not practical when there are many gameObjects. Ideally, we should seperate the rendering code from the gameObject code.
In order to ensure smooth animation display, the rendering code should be called as often as possible. Javascript has an additional timer, called requestAnimationFrame(). This timer will run as fast as the device allows. Faster devices will call this timer more frequently that slower devices when running the same program. Using requestAnimationFrame will always result in the best game rendering. The example below separates the gameObject update code from the rendering code.
Example of separate update and render code (Run Example)
<!-- Author: Derek O Reilly, Dundalk Institute of Technology, Ireland. --> <!DOCTYPE html> <html> <head> <title>Course notes example code</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> #gameCanvas { /* the canvas styling usually does not change */ outline:1px solid darkgrey; width:500px; height:500px; } </style> </head> <body> <canvas id = "gameCanvas"></canvas> <script> let imgImage = new Image(); imgImage.src = "images/map.png"; let carImage = new Image(); carImage.src = "images/car.png"; window.onload = function () { let canvas = document.getElementById("gameCanvas"); canvas.width = canvas.clientWidth; canvas.height = canvas.clientHeight; let ctx = canvas.getContext("2d"); let x = 0; animationInterval = setInterval(updateCarState, 25); // call renderCanvas function every 25 milliseconds renderCanvas(); // first call to renderCanvas function updateCarState() { if (x > (canvas.width + 1)) { x = 0; } else { x++; } } function renderCanvas() { ctx.drawImage(imgImage, 0, 0, canvas.width, canvas.height); // clear any previous drawing ctx.drawImage(carImage, x, 240, 40, 20); requestAnimationFrame(renderCanvas); // call renderCanvas again as soon as possible } }; </script> </body> </html>
Copyright Derek O' Reilly, Dundalk Institute of Technology (DkIT), Dundalk, Co. Louth, Ireland.