As I was preparing a session for my colleagues on the wonders of SVG, it appeared to me that a simple game would be a great way to show off not just the capabilities of SVG in the browser but also the ease with which SVG can be created and made to sing and dance. Well, may not really sing and not very much dancing, but still a lot of festive movement.
The game is quite simple: once started, a number of blue squares is randomly sprinkled around the play ground. With the red player marker the player has to touch each square as quickly as possible. Once all squares have been eliminated, the goal is reached, the game is over and the elapsed time is noted.
Let’s briefly discuss the code – to show you how simple it is to create a game like this – and much more interesting games as well.
The page with this game contains very little HTML:
This is it. A body element that contains an SVG element with a predefined size. The function doSVG that is called when the page is loaded takes care of preparing and running the game.
The global variable svg is set with a reference to the SVG element – the parent container for all SVG objects. Function addTargets() is called to create the blue squares that need to be sweeped by the player. Function showScore() shows the scoreboard (with currently the number of squares removed so far). Function showClock() shows …. well, what do you think it shows? It also refreshed itself, every 100 ms – as instructed through the setInterval() call.
Here is showClock():
It draws an SVG text element containing the elapsed time. The one complexity: once the player has swept all target elements, the clock should be stopped – the endtime.
Here is the function that renders the targets – the blue squares:
The numberOfTargets is an adjustable global setting. The hard coded blue fill color can easily be adjusted. The position and size of each target is determined somewhat randomly, using the randomInteger function. After 15 seconds, each square is dissolved – triggered by setTimeout – because that is when the game is over. The function dissolveTargets uses a D3 transition to get rid of the target shapes:
In three seconds, the squares are shrunk to 1% of their original size and are moved in the up and left direction.
The Player marker is created in function preparePlayer:
A simple rectangle in a randomized starting position, filled in bright red. The size of the player control is one of the aspects that could be changed with game level. A drag (& drop) handler is associated with the player control. The important action is the drag action. The position of the player control is adjusted in response to the drag event (to the position of the mouse cursor). Next, function checkPlayerOnTarget is invoked to check whether the player control has hit upon one or more targets.
This function is also quite straightforward. It iterates over all targets and for each target checks if the current position of the player control given the size of the control relative to the position of the target and its size means that the player control overlaps with the target and there the target can be taken out of play – spliced out of the targets array (and the score should be increased).
All targets in the collidedTargets collection are transitioned in 1 second to 1/100th of their former size and from their current color (blue) to yellow. The score is increased with the number of targets that was erradicated and the scoreboard is updated (call to showScore())
If no more targets are left – the game is over and the clock can be stopped. The Game Over message is presented to the player:
Another D3 transition or SVG animation – transitioning the text Game Over from fairly small to quite big.
Upping the Ante
Very easy enhancements that can be made to this game with very little effort:
- make the squares shrink in size as the game progresses
- have the squares start out with randomly assigned values that are added to the score; make these values decrease as time progresses (so make sure you get the most valuable squares first)
- use different shapes and images instead of squares
- add deadly, poisonous shapes that mean death when touched
- introduce levels with increasing degrees of difficulty (smaller targets, smaller player marker, randomly moving targets targets)
The binding between data and SVG shapes used by D3.js make it easy to interpret interactions and manipulate shapes upon interaction. The transitions that D3.js allows us to define make it easy to introduce shapeshifting, color fading, resizing and moving around. With timers (timeout and interval) we can easily give shapes a life of their own.
It is important to realize that the speed of the browser in rendering the SVG objects allows us to simply redraw the scene whenever we feel like it (to the human eye it will just seem a natural transition from the previous scene).
The code for this game is included in a single XHTML document. It is part of a GitHub repo in which I have shared a number of simple examples of using SVG and D3.js: GitHub Repo https://github.com/lucasjellema/code-cafe-intro-to-svg.
I am not claiming that creating games like this is extremely useful, I am certainly not claiming that my code is the best, most compact way to creating even this game. But I do claim that SVG is a powerful tool for creating rich, interactive, appealing presentations of data in an easy way, accessible to almost any software developer. And I am claiming that it is fun to create this stuff.