O'Reilly logo

HTML5 Canvas by Jeff Fulton, Steve Fulton

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Putting It All Together

We are now ready to start coding our game. First, we will look at the structure of the game and some of the ideas behind the various algorithms we will employ to create it. After that, we will present the full source code for Geo Blaster Basic.

Geo Blaster Game Structure

The structure of the game application is very similar to the structure we started to build earlier in this chapter. Let’s take a closer look at the state functions and how they will work together.

Game application states

Our game will have seven distinct game application states. We will store these in constants:

const GAME_STATE_TITLE = 0;
const GAME_STATE_NEW_GAME = 1;
const GAME_STATE_NEW_LEVEL = 2;
const GAME_STATE_PLAYER_START = 3;
const GAME_STATE_PLAY_LEVEL = 4;
const GAME_STATE_PLAYER_DIE = 5;
const GAME_STATE_GAME_OVER = 6;

Game application state functions

Each individual state will have an associated function that will be called on each frame tick. Let’s look at the functionality for each:

gameStateTitle()

Displays the title screen text and waits for the space bar to be pressed before the game starts.

gameStateNewGame()

Sets up all the defaults for a new game. All of the arrays for holding display objects are reinitialized—the game level is reset to 0, and the game score is set to 0.

gameStateNewLevel()

Increases the level value by one, and then sets the “game knob” values to control the level difficulty. See the upcoming section Level Knobs for details.

gameStatePlayerStart()

Fades the player graphic onto the screen from 0 alpha to 1. Once this is complete, level play will start.

gameStatePlayLevel()

Controls the play of the game level. It calls the update() and render() functions, as well as the functions for evaluating keyboard input for player ship control.

gameStatePlayerDie()

Starts up an explosion at the location where the player ship was when it was hit by a rock, saucer, or saucer missile. Once the explosion is complete (all particles in the explosion have exhausted their individual life values), it sets the move to the GAME_STATE_PLAYER_START state.

gameStateGameOver()

Displays the “Game Over” screen, and starts a new game when the space bar is pressed.

Game application functions

Aside from the game application state functions, there are a number of functions we need for the game to run. Each state function will call these functions as needed:

resetPlayer()

Resets the player to the center of the game screen and readies it for game play.

checkForExtraShip()

Checks to see whether the player should be awarded an extra ship. See the section Awarding the Player Extra Ships for details on this algorithm.

checkForEndOfLevel()

Checks to see whether all the rocks have been destroyed on a given level and, if so, starts up a new level. See the section Level and Game End for details on this algorithm.

fillBackground()

Fills the canvas with the background color on each frame tick.

setTextStyle()

Sets the base text style before text is written to the game screen.

renderScoreBoard()

Is called on each frame tick. It displays the updated score, number of ships remaining, and the current FPS for the game.

checkKeys()

Checks the keyPressList array, and then modifies the player ship attributes based on the values found to be true.

update()

Is called from GAME_STATE_PLAY_LEVEL. It in turn calls the update() function for each individual display object array.

Individual display object update() functions

The unique functions listed below update each different type of display object. These functions (with the exception of updatePlayer()) will loop through the respective array of objects associated with its type of display object, and update the x and y values with dx and dy values. The updateSaucer() function contains the logic necessary to check whether to create a new saucer, and whether any current saucers on the screen should fire a missile at the player.

  • updatePlayer()

  • updatePlayerMissiles()

  • updateRocks()

  • updateSaucers()

  • updateSaucerMissiles()

  • updateParticles()

render()

Is called from GAME_STATE_PLAY_LEVEL. It in turn calls the render() function for each individual display object array.

Individual display object render() functions

Like the update() functions, the unique functions listed below render each different type of display object. Again, with the exception of the renderPlayer() object (because there is only a single player ship), each of these functions will loop through the array of objects associated with its type and draw them to the game screen. As we saw when drawing the player ship earlier in this chapter, we will draw each object by moving and translating the canvas to the point at which we want to draw our logical object. We will then transform our object (if necessary) and paint the paths to the game screen.

  • renderPlayer()

  • renderPlayerMissiles()

  • renderRocks()

  • renderSaucers()

  • renderSaucerMissiles()

  • renderParticles()

checkCollisions()

Loops through the individual game display objects and checks them for collisions. See the section Applying Collision Detection for a detailed discussion of this topic.

firePlayerMissile()

Creates a playerMissile object at the center of the player ship and fires it in the direction the player ship is facing.

fireSaucerMissile()

Creates a saucerMissile object at the center of the saucer and fires it in the direction of the player ship.

playerDie()

Creates an explosion for the player by calling createExplode(), as well as changing the game application state to GAME_STATE_PLAYER_DIE.

createExplode()

Accepts in the location for the explosion to start and the number of particles for the explosion.

boundingBoxCollide()

Determines whether the rectangular box that encompasses an object’s width and height is overlapping the bounding box of another object. It takes in two logical display objects as parameters, and returns true if they are overlapping and false if they are not. See the section Applying Collision Detection for details on this function.

splitRock()

Accepts in the scale and x and y starting points for two new rocks that will be created if a large or medium rock is destroyed.

addToScore()

Accepts in a value to add to the player’s score.

Geo Blaster Global Game Variables

Now let’s look at the entire set of game application scope variables needed for our game.

Variables that control screen flow

These variables will be used when the title and “Game Over” screens first appear. They will be set to true once the screen is drawn. When these variables are true, the screens will look for the space bar to be pressed before moving on to the next application state:

var titleStarted = false;
var gameOverStarted = false;
Game environment variables

These variables set up the necessary defaults for a new game. We will discuss the extraShipAtEach and extraShipsEarned in the section, Awarding the Player Extra Ships:

var score = 0;
var level = 0;
var extraShipAtEach = 10000;
var extraShipsEarned = 0;
var playerShips = 3;
Playfield variables

These variables set up the maximum and minimum x and y coordinates for the game stage:

var xMin = 0;
var xMax = 400;
var yMin = 0;
var yMax = 400;
Score value variables

These variables set the score value for each of the objects the player can destroy:

var bigRockScore = 50;
var medRockScore = 75;
var smlRockScore = 100;
var saucerScore = 300;
Rock size constants

These variables set up some human-readable values for the three rock sizes, allowing us to simply use the constant instead of a literal value. We can then change the literal value if needed:

const ROCK_SCALE_LARGE = 1;
const ROCK_SCALE_MEDIUM = 2;
const ROCK_SCALE_SMALL = 3;
Logical display objects

These variables set up the single player object and arrays to hold the various other logical display objects for our game. See the upcoming sections and Arrays of Logical Display Objects for further details on each:

var player = {};
var rocks = [];
var saucers = [];
var playerMissiles = [];
var particles = []
var saucerMissiles = [];
Level-specific variables

The level-specific variables handle the difficulty settings when the game level increases. See the section Level Knobs for more details on how these are used:

var levelRockMaxSpeedAdjust = 1;
var levelSaucerMax = 1;
var levelSaucerOccurrenceRate = 25
var levelSaucerSpeed = 1;
var levelSaucerFireDelay = 300;
var levelSaucerFireRate = 30;
var levelSaucerMissileSpeed = 1;

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required