Lesson 24: Using an Array to Manage a Group of Elements

JavaScript, like almost all scripting and programming languages, support Arrays. An Array is like a variable, except that it can hold many values intead of just one.


A variable named age could be visualized like this:

age
22

Here, age has the value of 22. It can have any value, but only one. You declare a variable using:
var age;

You assign a value to a variable using:
age = 22;

You can also assign a value at the same time you declare the variable:
var age = 22;

You have used variables to store numbers (decimals and integers), Strings (comprised of numbers, letters, and other characters), Boolean values (true and false), and even Objects (such as HTML elements).


An Array named ages could be visualized like this:

ages
22
18
31
25
22

0
1
2
3
4

Here, ages has multiple values of 22, 18, 31, 25, and 22. It can have any number of values. The index (shown here under each value in red) is used to specify an element of the Array.

The first element of an Array always has an index of 0. The Array above has a length of 5, with index values from 0 to 4.

You declare an Array using:
var ages = new Array(); // ages is technically a variable with one value... an Array object.

You assign a value to an Array using:
ages[0] = 22;
ages[1] = 18; // the index (or position) must be specified

You can also assign a value at the same time you declare the variable:
var age = new Array(22, 18, 31, 25, 22);

You can read more about Arrays at: http://www.w3schools.com/jS/js_arrays.asp


With that brief lesson on Arrays, you should be ready to use an Array to manage many walls to be displayed on the gameWindow

In the last lesson you added a wall dynamically in the loadComplete() function.

This would be alot of repitition to write this code for every single wall, and definitely would not work well if the number of walls varied. You need to move this code into a function that you can quickly use as often as you want.

1. Delete the var wall_1; global variable. You will be using an Array to keep track of your walls instead of individual variables.

2. Move the code for creating a wall into a new function called createWall() that receives four agruments, the left, top, width, and height of the wall you are creating. Also call the createWall function at the end of loadComplete() to create a wall at position (200, 300) and with a size of 200px by 40px.

Modify createWall():

Now the wall is appearing. However, some functionality (such as wall collision detection) is no longer working.

This is because we deleted the declaration of wall_1, but still are trying to use it in the code in several places, including this code at the bottom of loop().

You are not ready to modify this code yet. You cannot replace wall_1 with wall because wall is a local variable that can only be used in the createWall() function. Besides, we want this conditional statement to check if pacman hit any wall, not just one particular wall.

3. Declare walls as a global Array to keep track of all the walls.

4. At the bottom of createWall(), add the wall that was just created to the walls Array.

First declare numWalls as a variable and set it equal to the current length of walls using the length property of an Array. The first time a wall is created before it is added to the Array, numWalls would be zero. Use numWalls as the index of the next open spot in the Array. The first time this code runs, wall will be added to walls at position 0. The second time this code runs, the new wall will be added to walls at position 1. After adding an element to walls, change the contents output to display the current number of walls (the length of the Array).

5. JavaScript provides several ways to add and remove elements from an Array. Simplify the code to add the wall to the end of walls using the Array's push() function.

6. In the loadComplete() function, add a second wall at the top of gameWindow.

The output div shows accurately that there are now two walls. Unfortunately, the rounded corners are leaving a small white corner.

7. To get rid of the unwanted whit space, modify the wall to stretch past the sides of the gameWindow.

8. Add two walls to the left side of gameWindow. Add some comments as well to organize the walls. This will be helpful as you begin to make more and more of them.

Note that pacman is 40px by 40px in size. Therefore, making the walls have a width of 40px, and making the spaces between wall be 40px, should work out well.

9. Add left side walls and a bottom wall.

Notice how easy it is to add walls after creating the createWall() function. Placing the walls might take some time though. For instance, it is clear that the inside wall is placed to closely to the bottom wall, not leaving enough space for Pacman to go through.

10. Move the inside wall up.

11. And move pacman's starting position up as well.

Now pacman should be able to fit between the walls perfectly.

It's time that you fix the collision detection.

12. Pressing Command-F or Control-F in most text editors will bring up the "Find" window. Type in wall_1 to the search bar and press enter. This will make it easy to find all instances of the wall_1 variable that you need to deal with. As you code grows larger, using "Find" is a nice way to find something you are looking for more quickly.

13. The first instance of wall_1 is at the bottom of the loop() function. Change the conditional statement to call hitWall(), a function you will create that checks if pacman hits any of the walls in the Array.

14. Create the hitWall function, and have it return true if pacman is hitting a wall and false if pacman is not hitting a wall.

Here, hit is declared and set equal to false. Then a hittest is done with each of the seven walls. If pacman hits any of the walls, hit is set to true. Finally, the value of hit is returned. Note that else is being used because as soon as one hit is detected, there is no reason to check any of the remaining walls.

Now pacman stops when he collides with any wall.

However, there are still issues in changing pacman's direction. This is because there are still wall_1 instances that need to be dealt with.

16. Find the next instances of wall_1 that are in the conditional statements of 'keydown' event listener. Modify these conditions to check if pacman did not hit any wall.

Things are working much better now.

There are still issues though. Notice that when moving up or down the side wall, it is difficult to turn into the gap. This is because pacman only tries to turn at the moment a key is pressed. It would be much more easy to turn if you could hold down an arrow so that pacman would coninue trying to change his direction every time he moves. Yes, we have to change how pacman moves once again.

Instead of attempting to change pacman's direction in the 'keydown' event listener, you want to continually attempt to change pacman's direction every time he moves. To do this, we again need to keep track of what arrow keys are down.

17. Add the global variables back in for tracking which arrow keys are being pressed down.

18. Add the 'keydown' and 'keyup' event listeners back to update the value of these variables every time an arrow key is pressed or released.

19. Change the previous 'keydown' event listener to a function called tryToChangeDirection that you will call anytime you want pacman to attempt to change his direction. Note that the function should end with a } instead of }); because it is no longer an argument of the addEventListener function. Also, event.keyCode cannot be used now because this code is not within an event listener and there is no event. Instead, change the conditional statements to use the variables that are being used to keep track of which arrow keys are being pressed.

20. This code will never occur if tryToChangeDirection() is never called. Add the function call to the top of loop(). You want it in the loop() because you want to continually be trying to change pacman's direction based on which arrow keys are being pressed.

All should be working well now.


Test Yourself!