HTML5 Canvas [156]
newSaucer.fireRate = levelSaucerFireRate;
newSaucer.fireDelay = levelSaucerFireDelay;
newSaucer.fireDelayCount = 0;
newSaucer.missileSpeed = levelSaucerMissileSpeed;
Missiles
Both the player missiles and saucer missiles will be 2×2-pixel blocks. They will be stored in the playerMissiles and saucerMissiles arrays, respectively.
The objects are very simple. They contain enough attributes to move them across the game screen and to calculate life values:
newPlayerMissile.dx = 5*Math.cos(Math.PI*(player.rotation)/180);
newPlayerMissile.dy = 5*Math.sin(Math.PI*(player.rotation)/180);
newPlayerMissile.x = player.x+player.halfWidth;
newPlayerMissile.y = player.y+player.halfHeight;
newPlayerMissile.life = 60;
newPlayerMissile.lifeCtr = 0;
newPlayerMissile.width = 2;
newPlayerMissile.height = 2;
Explosions and particles
When a rock, saucer, or the player ship is destroyed, that object explodes into a series of particles. The createExplode() function creates this so-called particle explosion. Particles are simply individual logical display objects with their own life, dx, and dy values. Randomly generating these values makes each explosion appear to be unique. Particles will be stored in the particles array.
Like missiles, particle objects are rather simple. They also contain enough information to move them across the screen and to calculate their life span in frame ticks:
newParticle.dx = Math.random()*3;
newParticle.dy = Math.random()*3;
newParticle.life = Math.floor(Math.random()*30+30);
newParticle.lifeCtr = 0;
newParticle.x = x;
newParticle.y = y;
Level Knobs
Even though we never show the level number to the game player, we are adjusting the difficulty every time a screen of rocks is cleared. We do this by increasing the level variable by 1 and then recalculating these values before the level begins. We refer to the variance in level difficulty as knobs, which refers to dials or switches. Here are the variables we will use for these knobs:
level+3
Number of rocks
levelRockMaxSpeedAdjust = level*.25;
Rock max speed
levelSaucerMax = 1+Math.floor(level/10);
Number of simultaneous saucers
levelSaucerOccurrenceRate = 10+3*level;
Percent chance a saucer will appear
levelSaucerSpeed = 1+.5*level;
Saucer speed
levelSaucerFireDelay = 120-10*level;
Delay between saucer missiles
levelSaucerFireRate = 20+3*level;
Percent chance a saucer will fire at the player
levelSaucerMissileSpeed = 1+.2*level;
Speed of saucer missiles
Level and Game End
We need to check for game and level end so we can transition to either a new game or to the next level.
Level end
We will check for level end on each frame tick. The function to do so will look like this:
function checkForEndOfLevel(){
if (rocks.length==0) {
switchGameState(GAME_STATE_NEW_LEVEL);
}
}
Once the rocks array length is 0, we switch the state to GAME_STATE_NEW_LEVEL.
Game end
We do not need to check for the end of the game on each frame tick. We only need to check when the player loses a ship. We do this inside the gameStatePlayerDie() function:
function gameStatePlayerDie(){
if (particles.length >0 || playerMissiles.length>0) {
fillBackground();
renderScoreBoard();
updateRocks();
updateSaucers();
updateParticles();
updateSaucerMissiles();
updatePlayerMissiles();
renderRocks();
renderSaucers();
renderParticles();
renderSaucerMissiles();
renderPlayerMissiles();
frameRateCounter.countFrames();
}else{
playerShips--;
if (playerShips<1) {
switchGameState(GAME_STATE_GAME_OVER);
}else{
resetPlayer();
switchGameState(GAME_STATE_PLAYER_START);
}
}
}
This is the state function that is called on each frame tick during the GAME_STATE_PLAYER_DIE state. First, it checks to see that there are no longer any particles on the screen. This ensures that the game