Lesson 46: Nested Loops

The last lesson had some pretty heavy math. It's time to take a break from that and blow some stuff up.

1. In the gameloop() function, within the block of code that executes when a collision between an enemy ship and the player's ship occurs, call the explode() function twice; once to explode the player's ship and once to explode the enemy ship.

2. Now create the explode function that will cause an explosion at the same location of the element that is passed to it.

explosion.gif is an animated gif that was included in the project files for this set of lessons. Unlike most animated gifs that are saved to loop forever, explosion.gif plays only once. Because the last frame of the animated GIF is transparent, the image is not visible once the animation plays one time through.

Adobe Photoshop allows you to save animated GIFs to only play once. You can also do this with GIMP, a free photo editing program.

Recall from a previous lesson that you already created a for loop within the gameloop() function to move all of the bullets.

3. Expand on the else block of this code (the portion that actually moves a bullet forward) so that it also checks if that bullet collides with any of the enemies.

Note that there is now a for loop inside another for loop. These are nested loops. The first loop is looping through each bullet, and for each bullet another loop is used to loop through each of the enemies to see if any of them collide with the bullet.

It is important to use a different variable to iterate through the bullets and the enemies. In this case, you are using i to iterate through the bullet elements and j to iterate through the elements in the enemies Array.

When a collision occurs, the bullet is removed from the bullets div, the explosion is started at the location of the enemy, and the enemy is placed back above the gameScreen. Because the explosion occurs in the location of the element that is passed in the explode() function, it is important that explode() is called prior to placeEnemyShip().

Deep Thought

Without the break command, the game will still run but you will see an error in the console log when firing. The error is a result of accessing an Array element that does not exist. Imagine there are 5 bullets in the bullets Array. When a collision between a bullet and an enemy occurs, the bullet is removed from the bullets Array. However, the inner loop continues trying to check that bullet for collisions with the remaining enemy ships--even though the bullet was removed.

A break command will break out of the inner most loop. In this case, once the bullet collides with one ship (and is removed from the Array), we do not want it continuing the loop to test with collisions of other ships. Note we are not breaking out of the outer loop so the remaining bullets are still tested for enemy collisions.

Now you should be able to destroy enemy ships for as long as you like.

However, you may notice in some browsers that the animated explosion only plays once, or until the first explosion is complete. This is because the browser is downloading the image only once and just re-using that same image; which in this case is set to only loop one time.

4. Force explosion.gif to be re-downloaded every time an explosion occurs.

You can do this by tricking the browser into downloading the same image by using a different URL.

In this case, we are adding on a variable (x) to the end of the URL with a value from the JavaScript Date.now() method that is always different - the number of milliseconds elapsed since 1 January 1970 00:00:00 UTC.

Modifying the URL in this way is a common method for forcing a browser to reload a page, or in this case an image, that is already cached on the users machine.


Test Yourself!

Practice with for loops nested (and learn about jsFiddle)