In recent years I decided I wanted to create a mini game using HTML 5 Canvas and pure JavaScript because I always wanted to understand how games work (the simple ones at least). Growing up in the 90’s I remember playing the infamous Space Invaders on the Nintendo and therefore I decided to create a spin off based on the same concept named The Last Stand.
The hero fighter space ship has to fight off waves of attacking aliens to regain control of the solar system. Each level gets harder as the intensity of the game increases and the levels are decorated and named after planets from Pluto to Mercury (yeah I know Pluto isn’t a planet) until the final battle takes place near the sun. In this post I will be going through the phases on how I went about developing this game and provide source code.
Live demo can be played [here].
*mobile not supported.
Please note you might need to zoom out on your browser to make it fit depending on screen size and resoltution. The game controls are simple: Left and Right arrow keys for movement and Space Bar for shooting.
Enjoy!
1. Canvas and Frames
The minimum you need to create an HTML 5 game is a canvas and two JavaScript methods: onload() where game objects like Sprites are loaded (more in this later) and loop() where things like rendering and object positions are updated or created into the canvas. Traditionally if you wanted to create a method which loops infinitely in JavaScript, you’d use the setInterval() function however modern browsers have something called requestAnimationFrame which can be used to provide a Frames per second loop which is more optimised for CPU and Battery use and also for smoother animation performance. The implementation of such method can be found [here].
The gameStart() method will load all the game objects and sprites and then the loop() method will be called. The loop() method itself calls requestAnimFrame(loop) which callbacks the method indefinitely creating a smooth FPS loop.
2. Game Sprites and Animations
In order to create object styles and animations, the most efficient way is to use Sprite images. In the base class I have created two methods: Sprite() and AnimationSprite(). The difference is that Sprite() will load the image with the coordinates given and remain a static non moving image whilst animated sprites will be loaded with multiple frames and played as a sequence kind of like a movie. To give an example, the explosion animation is loaded as an image sprite as follows and then played piece by piece to make it look like an organic fiery explosion.
Since I was having fun with JavaScript I decided to structure the code in a clean OOP and since these methods could apply to any other game, I placed this code in the base class [here]. The image assets which were used in this game were found online a few years back and my designer colleagues helped me with some touches, I don’t have references from where these were found but of course, many free resources can be found online or design your own.
3. Game Input Controls
The controls are pretty simple in this game: Enter to start, Left and Right to move and Space Bar to shoot. JavaScript event listeners were used to track the keyboard inputs, the code can be found [here]. At each loop iteration, the key input controls are read and actions are taken accordingly like changing the x and y position of an object on the canvas. For instance, the code responsible for moving the tank can be found [here].
4. Rendering
Objects inside the game are kept in distinct arrays and at each loop iteration, the canvas is cleared and rendered again. At each loop iteration, there are various methods being called which make checks (such as collision detection) and updates of animations or positions which make the game come to life. The update() method is responsible for calling all the update methods individually followed by the render() method which redraws all the sprite objects on canvas.
5. Collision Matrix
AABB Intersection (Axis-Aligned Bounding Box) is an algorithm used to determine whether objects on a 2D come to an intersection (or collision) at a given moment. Given the width, height, position x and position y of two objects, the AABBIntersect method calculates the collision matrix and returns true or false. This method is the real hero of the game since it’s able to intercept all hits being fired by the tank and the aliens ships at every loop cycle. When a collision is triggered. animations and sounds can be played accordingly to enhance the game experience.
6. Game-play design
Below is a sequence diagram illustrating how the game works.
The aliens are programmed to move in a sequence to the side and down approaching the tank which is controller by the user. The alien ships produce a random shot attack (only if the alien ship is on front-line and not obstructed by other alien ships). The tank creates fire shots at the Space Bar press. The bullets follow a straight line trajectory and destroy any object which is encountered by calculating the collision matrix of each object at each loop cycle.
The score is updated at each successful hit and the level difficulty is increased when all aliens on canvas are cleared.
The full source code can be found [here].
7. Game Enhancements
For level design enhancement, THREE.JS framework can be used in order to create a background design with special effects containing planets in motion during the game-play such as I did here on the [live demo].
Also used Howler.js, a great framework for playing sound effects during the game using mp3 files.
Finally, I used geolocation tracking in the live demo (mostly because I wanted to experiment with this) and depending on the region you are from in the world, a different ship is generated.
Conclusion
In this post, it was demonstrated that with basic JavaScript and HTML 5 canvas a simple and pretty looking game can be created (if you happen to have good designer friends like myself).
So… how much score can you get? Go[here] to find out!.
References
1. Code Structuring tips for HTML 5 games
http://blog.sklambert.com/html5-game-tutorial-module-pattern/
2. Collision Matrix (AABB Intersection)
https://developer.mozilla.org/en-US/docs/Games/Techniques/2D_collision_detection
3. THREE.JS Framework (Planets)
https://github.com/jeromeetienne/threex.planets
4. Howler.JS JavaScript sound framework
https://github.com/goldfire/howler.js/