Game rendering loop using HTML canvas and Typescript
Sandro Maglione
Get in touch with meGames
15 June 2023
•7 min read
Sandro Maglione
Games
It's common when working with a game engine to have an update
or render
method.
This method gets called on every frame and allows you to update the current state of the game.
In this article we are going to implement a Game/Animation rendering loop using Typescript and HTML canvas
.
Here is the final code (copy-paste ready ✅):
Rendering lifecycle in games: Unity
In Unity for example, every script class inherits from MonoBehaviour
.
MonoBehaviour
gives you access to 2 main methods:
Start()
: Used for initializationUpdate()
: Used for updates (called once per frame)
The Update
function allows to update the current state of the game. This might include movement, triggering actions, responding to user input, anything that needs to be handled over time during gameplay.
The Start
function is called only once at the beginning of the lifecycle. It allows to initialize the state.
Update
andStart
are the 2 main methods used to implement a game rendering loop
There is more.
Every week I build a new open source project, with a new language or library, and teach you how I did it, what I learned, and how you can do the same. Join me and other 600+ readers.
Rendering loop using HTML canvas
On the web we can achieve a similar result using <canvas>
.
canvas
can be used for animations, game graphics, data visualization, photo manipulation, and real-time video processing
Let's start by adding a canvas
tag with a custom id
, width
and height
:
The goal now is to implement a function that gives as access to the Canvas Rendering Context and that runs a continuous loop at every frame.
requestAnimationFrame
: Rendering loop
window
provides a requestAnimationFrame
method.
requestAnimationFrame
is used to perform animations on the web. It tells the browser to call a specified function to update an animation right before the next repaint.
Note: A single
requestAnimationFrame
request animates 1 single frame. In order to have a continuous loop we need to invokerequestAnimationFrame
recursively.
requestAnimationFrame
allows to pass a callback function that will be called before the next repaint.
The callback function provides 1 parameter which is the time (in milliseconds) in which the function is called (the time is of type DOMHighResTimeStamp
):
delta
time: Time between each frame
A game loop also provides a delta
time (called Time.deltaTime
in Unity for example).
delta
: The interval from the last frame to the current one
This value is used to perform animations, since it allows to gradually update the position of an object after every frame.
We can compute this value using the time
parameter provided by the requestAnimationFrame
callback function:
The update
function implements the game rendering loop.
It provides an onUpdate
function, which allows to update the state after every frame (equivalent to Update ()
in Unity).
Accessing canvas
in the rendering loop
The final step is getting access to canvas
inside the rendering loop:
The renderer
function accepts 3 parameters:
onInit
: Initialize the state (equivalent toStart ()
in Unity)onUpdate
: Update the state at every frame (equivalent toUpdate ()
in Unity)id
: Referenceid
of thecanvas
("canvas"
by default)
Inside renderer
we get access to canvas
and ctx
and then start the rendering loop by calling window.requestAnimationFrame
.
How to use renderer
That's all! Now you can simply call renderer when the webpage loads and use onInit
and onUpdate
to define your game/animation logic:
Here is the final complete code 👇:
This is all you need to implement a basic game loop on the web using typescript and canvas
.
I personally used this to create a simulation of a natural selection environment running directly on my browser:
This rendering loop is ideal for creating animated simulations, simple games, and algorithm visualizations, all with a single renderer
function running on the web 🪄
If you found this article helpful or interesting, you can subscribe to my newsletter here below for similar content 👇
Thanks for reading.