A tutorial to recreate Space Invaders with HTML and JavaScript
Do you want to add a simple 2D game to your website? Or do you want to learn the basics of creating 2D games? This article explains how to recreate the classic Space Invaders game for most modern browsers with only HTML, and JavaScript.
It can be a great idea to specify the basic features of a game before starting the development to get an overview of the work that needs to be done.
The game’s specifications can be defined as follows:
- The game requires an object that can be moved, drawn to the canvas’ surface, and provides collision checks.
- The enemy and player objects should be able to fire bullets toward each other.
- A bullet object should only be able to move in one direction.
- The player object should only be able to move left and right on the x-axis within the canvas’ borders.
- An asteroid object should consist of several destroyable parts.
- The game should restart if all the enemies are destroyed, or if one of the enemies reaches the position of the player on the y-axis.
The game’s objects
The class diagram in figure 1 shows an overview of the game’s different classes and their relations. It can for example be seen that all visual objects are created by the base class GameObject, or that the Player class is inheriting properties and behavior from both the SpaceShip and the GameObject class.

The first step is to set up the HTML document with a canvas element (See figure 2). An HTML canvas provides the ability to draw various 2D graphics (Mozilla, 2022a).
It is for example possible to draw simple shapes or images inside the canvas (Mozilla, 2022b) (Mozilla, 2022c). The canvas element in figure 2, line 9, is defined with the id
, width
and height
properties.
The id
property is used to reference the canvas element in JavaScript, and the width
and height
properties simply specify the dimensions of the canvas.
The next step is to set up a JavaScript object that can be used to hold different properties and behavior (Mozilla, 2022d). Figure 3, line 12, shows an implementation of the Javascript object, which is called game
.
The idea behind using a JavaScript object to hold properties and behavior in this tutorial is to avoid the game’s logic being available as a lot of global variables and functions.
General properties
Three properties are added to the game
object on lines 15–19, in figure 3. The canvas
property refers to the HTML canvas element, ctx
refers to the interface, that can be used to draw on the canvas surface (Mozilla, 2022e), and backgroundColor
refers to the canvas’ background color.
General behavior
Five methods are added to the game
object on lines 22–43, figure 3. update()
defines the game’s continuous behavior, such as drawing elements, moving elements, etc. The first two lines within the update()
method (lines 24–25, figure 3) set the background of the canvas to the value of the backgroundColor
property.
Redrawing the background for each time update()
is called ensures objects which are moving will be drawn at the new position instead of both the new and old position.keydown()
defines what should happen if a key on the keyboard was pressed. init()
defines the initialization of the game which starts the game loop. stop()
defines how to stop the game loop, and restart()
defines how to restart the game.
A class called GameObject is added to define the general behavior of objects used within the game. The general game object contains five properties. x
and y
defines the position of the game object. width
and height
defines the size of the game object’s rectangle, and color
defines the color of the rectangle.
The GameObject class also contains three methods. draw()
is used to draw the game object within the canvas. update(dx, dy)
move the game object in any given direction, and collidesWith(obj)
returns true if a given game object overlaps with the game object.
After adding the GameObject class, a simple Bullet class can be added which inherits the properties and behavior from the GameObject class.
The Bullet class contains an additional property called dy
which is used to define the direction the bullet should move on the y axis. The update(dx, dy)
method inherited from the GameObject class is overridden in the bullet class (see lines 22–25, figure 5) to define it always should move towards the given start direction.
A class called SpaceShip is added to define the general properties and behavior of the player and enemy objects. The SpaceShip class is also a subclass of the GameObject class.
The SpaceShip class has five additional properties. canvasHeight
is used to specify the boundaries for the bullets fired by a SpaceShip. bulletWidth
and bulletHeight
defines the dimension of the bullets. bulletColor
defines the color of the bullets, and bullets
is an array used to specify bullets spawned by a SpaceShip.
The SpaceShip class is designed to override the draw(ctx)
method inherited from the GameObject class to implement a check removing bullets outside of the screen and to implement a loop drawing and moving bullets.
The SpaceShip class also includes an additional method called shoot(dy)
which is used to spawn bullets moving towards the given direction on the y axis.
A Player class is added as a subclass of the SpaceShip class to implement properties and behavior specific to the player object.
The Player class has an additional property called canvasWidth
defining the width of the game’s canvas.

The property is used to check if the player is outside of the screen on the x-axis. The check is implemented by overriding the update(dy, dx)
method inherited from the parent class and adding some additional lines of code moving the player position on the x-axis either to zero or the canvas width minus the player width.
The last class needed is the Asteroid class. This class is not a subclass of the game object class, however, the class is closely connected to the game object class, because it contains a property called parts
which is an array of game objects.
This design allows an asteroid in the game to be destroyed part by part (see figure 9).

The Asteroid class also contains three methods. draw(ctx)
is used to draw the asteroid’s game objects. collidesWith(obj)
returns true if one of the asteroid’s game objects collides with the given game object, and removeOnCollide(obj)
removes one of the asteroid’s game objects if one of the asteroid’s game objects collids with the given game object.
Figure 11, lines 24–45 shows the implementation of the additional required game properties for the asteroids and enemies.
Additional Asteroid properties
asteroidsParts
defines the number of game objects an asteroid is made of, noOfAsteroids
is used to define the number of asteroids the game should contain, and asteroidsSpace
defines the space between each asteroid.
Additional enemy properties
enemiesEachLine
define the number of enemies that should be spawned on each line. enemyLines
defines the number of lines of enemies. enemySpace
defines the space between each enemy. enemyFireRate
defines how often enemies should fire a bullet, and enemyFireTimer
is a variable used to keep track of the time since the last shot. enemyDirection
defines if the enemies should move left or right (left = -1, right = 1), and enemyStep
defines how much the enemies should be moved on the y-axis when reaching either the left or right side of the canvas.
It is now possible to complete the game
object’s init()
method (see lines 27–62, figure 12). The method should include some additional lines of code defining how to create the player, the enemies, and the asteroids, at their start position.
This design allows using the game
object’s restart()
method, to reset the game to the initial state.
The game
object’s keydown()
method is called every time a user presses a key on the keyboard (see lines 23–36, figure 13). The specific key pressed can be read as a number from the argument e
by reading its property keyCode
.
For example, the number 37
defines the left arrow key, and the number 39
defines the right arrow key. The keydown()
method is designed to check if the user pressed one of the arrow keys, or the A-key and D-key, which moves the player either left or right. It also includes an additional check to detect whenever the user presses the space key which spawns a bullet at the player’s position.
The final method of the game that needs modification is the game
object’s update()
method (see lines 23–154, figure 14).
Draw the player, asteroids, and enemies
Lines 29–38, figure 14, simply call the draw(ctx)
method on the different objects to ensure they are drawn within the canvas. Line 39, figure 14, in the same loop drawing the enemies, moves the enemies towards the direction specified in the enemyDirection
property.
Enemy count check
Lines 43–46, figure 14, check if the game
object’s enemies
array is empty, and restarts the game if the check evaluates to true. This check could include some additional code decreasing a player’s life
property until it reaches zero, which then would restart the game.
Enemy movement
Lines 49–91, figure 14, check if the enemyDirection
property is either 1 or -1. If the property is 1, the method finds the enemy closest to the right side of the screen, and if that enemy reaches the right side, the method sets the enemyDirection
to -1 and moves all the enemies down by the value of enemyStep
. The opposite happens if the value of enemyDirection
is -1.
Enemy random shot
Lines 94–99, figure 14, increase the enemyTimer
property until a random enemy is selected to fire a shot that moves towards the player.
Bullet collision checks
Lines 102–154, figure 14, show four loops with almost the same behaviour. For example, the first loop, lines 101–110, figure 14, loops through all player bullets and checks if they collide with one of the astroids’ game objects. The third loop, lines 125–134, figure 14, loops through all player bullets and checks if one of the bullets collids with one of the enemies.
The complete code can be found at this link.
Mozilla. 2022a. Canvas API.
https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API.
Accessed: 28th June 2022
Mozilla. 2022b. Using images.
https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Using_images.
Accessed: 28th June 2022
Mozilla. 2022c. Drawing shapes with canvas.
https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes.
Accessed: 28th June 2022
Mozilla. 2022d. Working with objects.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects.
Accessed: 28th June 2022
Mozilla. 2022e. CanvasRenderingContext2D.
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D.
Accessed: 28th June 2022