HTML5 Canvas [157]
Once the particles and missiles have all left the game screen, we subtract 1 from the playerShips variable and then switch to GAME_STATE_GAME_OVER if the playerShips number is less than 1.
Awarding the Player Extra Ships
We want to award the player extra ships at regular intervals based on her score. We do this by setting an amount of points that the game player must achieve to earn a new ship—this also helps us keep a count of the number of ships earned:
function checkForExtraShip() {
if (Math.floor(score/extraShipAtEach) > extraShipsEarned) {
playerShips++
extraShipsEarned++;
}
}
We call this function on each frame tick. The player earns an extra ship if the score/extraShipAtEach variable (with the decimals stripped off) is greater than the number of ships earned. In our game, we have set the extraShipAtEach value to 10000. When the game starts, extraShipsEarned is 0. When the player’s score is 10000 or more, score/extraShipAtEach will equal 1, which is greater than the extraShipsEarned value of 0. An extra ship is given to the player, and the extraShipsEarned value is increased by 1.
Applying Collision Detection
We will be checking the bounding box around each object when we do our collision detection. A bounding box is the smallest rectangle that will encompass all four corners of a game logic object. We have created a function for this purpose:
function boundingBoxCollide(object1, object2) {
var left1 = object1.x;
var left2 = object2.x;
var right1 = object1.x + object1.width;
var right2 = object2.x + object2.width;
var top1 = object1.y;
var top2 = object2.y;
var bottom1 = object1.y + object1.height;
var bottom2 = object2.y + object2.height;
if (bottom1 < top2) return(false);
if (top1 > bottom2) return(false);
if (right1 < left2) return(false);
if (left1 > right2) return(false);
return(true);
};
We can pass any two of our game objects into this function as long as each contains x, y, width, and height attributes. If the two objects are overlapping, the function will return true. If not, it will return false.
The checkCollision() function for Geo Blaster Basic is quite involved. The full code listing is given in Example 8-12. Rather than reprint it here, let’s examine some of the basic concepts.
One thing you will notice is the use of “labels” next to the for loop constructs. Using labels such as in the following line can help streamline collision detection:
rocks: for (var rockCtr=rocksLength;rockCtr>=0;rockCtr--){
We will need to loop through each of the various object types that must be checked against one another. But we do not want to check an object that was previously destroyed against other objects. To ensure we do the fewest amount of collision checks necessary, we have implemented a routine that employs label and break statements.
Here is the logic behind the routine:
Create a rocks: label and then start to loop through the rocks array.
Create a missiles: label inside the rocks iteration, and loop through the playerMissiles array.
Do a bounding box collision detection between the last rock and the last missile. Notice that we loop starting at the end of each array so that we can remove elements (when collisions occur) in the array without affecting array members that have not been checked yet.
If a rock and a missile collide, remove them from their respective arrays, and then call break rocks and then break missiles. We must break back to the next element in an array for any object type that is removed.
Continue looping through the missiles until they have all been checked against the current rock (unless break rocks was fired off for a rock/missile collision).
Check each saucer, each saucer missile, and the player against each