Moving and Grooving Using JavaScript

In This Chapter

Moving an object onscreen
• Responding to keyboard input
• Reading mouse input
• Running code repeatedly
• Bouncing off the walls
Using image-swapping and compound images
Reusing code
Using external script files
JavaScript has a serious side, but it can be a lot of fun, too. You can easily use JavaScript to make things move, animate, and wiggle. In this chapter, you get to make your pages dance. Even if you aren’t interested in animation, you should look over this chapter to find out some important ideas about how to design your pages and your code more efficiently.

Making Things Move

You might think you need Flash or Java to put animation in your pages, but that’s not true. You can use JavaScript to create some pretty interesting motion effects. Begin by taking a look at Figure 8-1.
Because this chapter is about animation, most of the pages feature motion. You really must see these pages in your browser to get the effect because a static screen shot can’t really do any of these programs justice.
The general structure of this page provides a foundation for other kinds of animation:
The HTML is pretty simple. As you’ll see when you pop the hood, there really isn’t much to the HTML code. It’s a couple of divs and some buttons.
Click the buttons, and the ball moves.
Figure 8-1:
Click the buttons, and the ball moves.
The ball is in a special div called sprite. Game developers call the little images that move around on the screen sprites, so I use the same term.
The sprite div has a local style. JavaScript animation requires a locally defined style.
The sprite div has absolute positioning. Because I want to move this thing around on the screen, it makes sense that the sprite div is absolutely positioned.
The code and CSS are as modular as possible. Things can get a little complicated when you start animating things, so I take care through this chapter to simplify as much as I can. The CSS styles are defined externally, and the JavaScript code is also imported.
Code is designed to be reused. Many of the programs in this chapter are very similar to each other. To save effort, I’ve designed things so I don’t have to rewrite code if possible.


Looking over the HTML

The following HTML code for the move.html program provides the basic foundation:

tmp1121_thumb_thumb

You should notice a few interesting things about this code:

‘ It has an external style sheet. Most of the CSS (the stuff that defines the surface and the forms) is moved off-stage into an external style sheet. Some CSS has to be defined locally, but I have made as much of the CSS coding external as possible.
tmp1122_thumb_thumb
The JavaScript is also outsourced. The <script> tag has an src attribute, which you can use to load JavaScript code from an external file. The browser loads the specified file and reads it as though it were directly in the code. (Note that external scripts still require a </ script> tag.) This program gets its scripts from a file called movement.js.
tmp1123_thumb_thumb
The <body> tag calls a method. In animation (and other advanced JavaScript), you might have some code you want run right away. The body has an onload event. You can feed it the name of a function (just like you do with a button’s onclick event). In this case, I want the function called init() to run as soon as the body finishes loading into the computer’s memory.
tmp1124_thumb_thumb
The yellow box is a div called surface. It isn’t absolutely necessary, but when you have something moving around on the screen, it’s nice to have some kind of boundary so the user knows where she can move the sprite.
There’s a sprite div inside surface. This sprite will be the thing that actually moves around.
tmp1125_thumb_thumb
The sprite div has a local style. Your code can change only the styles that have been defined locally. The sprite div has a local style specifying absolute position, top, and left properties.
There’s a form for buttons. This particular program uses buttons to discern the user’s intent. When you use buttons, you should place them in a form (even though in this case the form isn’t absolutely necessary).
tmp1126_thumb_thumb
Each button calls the moveSprite() method. The moveSprite() method is defined in the movement.js file. It accepts two parameters: dx determines how much the sprite should move in the x (side to side) axis, and dy controls how much the sprite will move in the y (vertical) axis.

Getting an overview of the JavaScript

Because the JavaScript code is getting more complex, I recommend that you keep the following programming concepts in mind so that you can improve your programming efficiency:
Move code to an external file. As with CSS code, when the JavaScript starts to get complex, it’s a good idea to move it to its own file, so it’s easier to manage and reuse.
Encapsulate code in functions. Rather than writing a long, complicated function, try to break the code into smaller functions that solve individual problems. If you design these functions well, your code will be easier to write, understand, and recycle.
Create a few global variables. A few key variables will be reused throughout your code. Create global variables for these key items, but don’t make anything global that doesn’t need to be.
Define constants for clarity. Sometimes it’s handy to have a few key values stored in special variables. In movement.html, I’ve created some constants to help me track the boundary of the visual surface.

Creating global variables

The first part of this document simply defines the global variables I use throughout the program:
tmp1127_thumb_thumbtmp1128_thumb_thumb

The movement program has three main global variables:

sprite: Represents the div that will move around on the screen. x: Is the x (horizontal) position of the sprite. y: Is the y (vertical) position of the sprite.
It isn’t necessary to give values to global variables right away, but you should define them outside any functions so their values will be available to all functions. (Check Chapter 5 for more about functions and variable scope.)
Note that in computer graphics, the y axis works differently than it does in math. Zero is the top of the screen, and y values increase as you move down on the page. (This system is used because it models the top-to-bottom pattern of most display devices.)
This program also features some special constants. A constant is a variable (usually global) with a value that doesn’t change as the program runs. Constants are almost always used to add clarity.
Through experimentation, I found that the ball’s x value should never be smaller than 15 or larger than 365. By defining special constants with these values, I can make it clear what these values represent. (Look ahead to the boundary-checking code in the “Moving the sprite” section to see how this really works.)
Programmers traditionally put constants entirely in uppercase letters. Many languages have special modifiers for creating constants, but JavaScript doesn’t. If you want something to be a constant, just make a variable with an uppercase name and treat it as a constant. (Don’t change it during the run of the program.)

Initializing

The init() function is small but mighty:
tmp1129_thumb_thumb
It does a simple but important job: It loads up the sprite div and stores it in a variable named sprite. Because sprite is a global variable, all other functions will have access to the sprite variable and will be able to manipulate it.
You’ll often use the init() function to initialize key variables in your programs. You can also use this function to set up more advanced event handlers, as you see in the keyboard and mouse examples later in this chapter.

Moving the sprite

Of course, the most interesting function in the program is the one that moves sprites around the screen. Take a look at it and then look through my explanation for it.
tmp11210_thumb_thumb
The function essentially works by first determining how much the sprite should be moved in x and y, and then manipulating the left and top properties of its style.
1. Accept dx and dy as parameters.
The function expects two parameters: dx stands for delta-x, and dy is delta-y. (You can read them difference in x, difference in y if you prefer, but I like sounding like a NASA scientist.) These parameters tell how much the sprite should move in each dimension:
tmp11211_thumb_thumb
You might wonder why I’m working with dx and dy when this object moves only horizontally. See, I’m thinking ahead. I’m going to reuse this function in the next few programs. Even though I don’t need to move vertically yet, I will soon, so I included the capability.
2. Get a reference to the surface.
Use the normal document.getElementByld trick to extract the sprite from the page. Be sure the sprite you’re animating has absolute position with top and left properties defined in a local style.
tmp11212_thumb_thumb
3. Extract the sprite’s x and y parameters.
The horizontal position is stored in the left property. CSS styles are stored as strings and include a measurement. For example, the original left value of the sprite is 10 0px. For the program, we need only the numeric part. The parseInt() function pulls out only the numeric part of the left property and turns it into an integer, which is then stored in x. Do the same thing to get the y value.
tmp11213_thumb_thumb
4. Increment the x and y variables.
Now that you have the x and y values stored as integer variables, you can do math on them. It isn’t complicated math. Just add dx to x and dy to y. This allows you to move the object as many pixels as the user wants in both x and y axes.
tmp11214_thumb_thumb
5. Check the boundaries.
If you have young children, you know this rule: When you have something that can move, it will get out of bounds. If you let your sprite move, it will leave the space you’ve designated. Checking the boundaries isn’t difficult, but it’s another task, so I’m just calling a function here. I describe checkBounds() in the next section, but basically it just checks to see whether the sprite is leaving the surface and adjusts its position to stay in bounds.
tmp11215_thumb_thumb
6. Move the ball.
Changing the x and y properties doesn’t really move the sprite. To do that, you need to convert the integers back into the CSS format. If x is 120, you need to set left to 120px. Just concatenate “px” to the end of each variable.
tmp11216_thumb_thumb
7. Print out the position.
For debugging purposes, I like to know exactly where the x and y positions are, so I just made a string and printed it to an output panel.
tmp11217_thumb_thumb

Checking the boundaries

You can respond in a number of ways when an object leaves the playing area. I’m going with wrapping, one of the simplest techniques. If something leaves the rightmost border, simply have it jump all the way to the left.

The code handles all four borders:

tmp11218_thumb_thumb
The checkBounds() function depends on the constants. This helps in a couple of ways. When you look at the code, it’s really easy to see what’s going on:
tmp11219_thumb_thumb
If x is larger than the maximum value for x, set it to the minimum value. You almost can’t write it any more clearly than this. If the size of the playing surface changes, you simply change the values of the constants.
All this is very nice, but you probably wonder how I came up with the actual values for the constants. In some languages, you can come up with nice mathematical tricks to predict exactly what the largest and smallest values should be. In JavaScript, this technique is a little tricky because the environment just isn’t that precise.

Shouldn’t you just get size values from the surface?

In a perfect world, I would have extracted the position values from the playing surface itself. Unfortunately, JavaScript/DOM is not a perfect animation framework. HTML 5 supports a marvelous tag called the canvas, which serves as a perfect drawing and animating platform, but it isn’t available on all browsers yet.
Because I’m using absolute positioning, the position of the sprite isn’t attached to the surface (as it should be) but to the main screen. It’s a little annoying, but some experimentation
can help you find the right values. Remember, as soon as you start using absolute positioning on a page, you’re pretty much committed to it. If you’re using animation like this, you probably want to use absolute positioning everywhere or do some other tricks to make sure the sprite stays where you want it to go without overwriting other parts of the page. Regardless, using constants keeps the code easy to read and maintain even if you have to hack a little bit to find the specific values you need.
I chose a simple but effective technique. I temporarily took out the checkbounds() call and just took a look at the output to see what the values of x and y were. I looked to see how large x should be before the sprite wraps and wrote the value down on paper. Likewise, I found largest and smallest values for y.
When I knew these values, I simply placed them in constants. I don’t really care that the maximum value for x is 365. I just want to know that when I’m messing around with x I don’t want it to go past the MAX_X value.
If the size of my playing surface changes, I can just change the constants and everything will work out fine.
If you’re interested, here are the other techniques you can use when a sprite is about to leave the visual area:
Bounce: The object bounces off the wall. This is done by inverting the dx or dy value (depending on whether it’s a vertical or horizontal wall).
Stop: The object simply stops moving when it hits the wall. Set dx and dy to 0 to achieve this effect.
Continue: The object keeps moving even though it is out of sight. This is sometimes used for air-traffic control simulations (where visualizing the location is part of the game) or orbital simulations (where presumably the object will return).
Combinations: Sometimes you’ll see combinations like the civilization games that simulate a cylindrical map by stopping on the top and bottom and scrolling on the sides.

Reading Input from the Keyboard

You can use JavaScript to read directly from the keyboard. Reading from the keyboard can be useful in a number of situations, but it’s especially handy in animation and simple gaming applications.
Figure 8-2 shows a program with another moving ball.
You can move the ball with the arrow keys.
Figure 8-2:
You can move the ball with the arrow keys.
The keyboard.html page has no buttons because the arrow keys are used to manage all the input.
You know what I’m going to say. Look this thing over in your browser because it just doesn’t have any charm unless you run it and mash on some arrow keys.

Building the keyboard page

The keyboard page is very much like the movement.html page shown earlier in this chapter.
tmp11221_thumb_thumb
The keyboard.html page is very similar to the movement.html page described early in the chapter. This sort of situation is when it really pays off to build reusable code. I basically copied the movement.html page and made a couple of small but important changes:
Import the movement.js script. This page uses the same functions as the movement.html page, so just import the script.
Add another script specific to reading the keyboard. You need a couple of modifications, which are housed in a second script file called keyboard.js.
Keep the rest of the page similar. You still call init() when the body loads, and you still want the same visual design, except for the buttons.
The surface and sprite divs are identical to the movement.html design.
Take out the form. This page responds to the keyboard, so you don’t need a form any more.

Looking over the keyboard.js script

Remember that this program begins with the movement.js script. As far as the browser is concerned, that entire script file has been loaded before the keyboard.js script appears. The basic foundation is already in place from movement. The keyboard script just handles the modifications to make keyboard support work.

Overwriting the init() function

Working with a keyboard still requires some initialization. I need a little more work in the init() function, so I make a new version that replaces the version created in movement.js.
tmp11222_thumb_thumb
The order in which you import scripts matters. If you duplicate a function, the browser interprets only the last one it reads.

Setting up an event handler

In my init() function, I still want to initialize the sprite (as I did in movement.js). When you want to read the keyboard, you need to tap into the browser’s event-handling facility. Browsers provide basic support for page-based events (like body.onload and button.onclick), but they also provide a lower level of support for more fundamental input such as keyboard and mouse input.
If you want to read this lower-level input, you need to specify a function that will respond to the input.
tmp11223_thumb_thumb
This line specifies that a special function called keyListener will be called whenever the user presses a key. Keep the following things in mind when creating this type of event handler:
1. The event handler should be called in init().
You probably want keyboard handling to be available immediately, so you should set up event handlers in the init() function.
2. The function is called as though it were a variable.
This is a slightly different syntax than you’ve seen before. When you create function handlers in HTML, you simply feed a string that represents the function name complete with parameters (button onclick = “doSomethingO”). When you call a function within JavaScript (as opposed to calling the function in HTML), the function name is actually much like a variable, so it doesn’t require quotes.
If you want to know the truth, functions are variables in JavaScript. Next time somebody tells you JavaScript is a “toy language,” mention that it supports automatic dereferencing of function pointers. Then run away before the person asks you what that means. (That’s what I do.)
3. You need to create a function with the specified name.
If you have this code in init, the browser calls a function called keyListener() whenever a key is pressed. (You could call the function something else, but keyListener() is a pretty good name for it because it listens for keystrokes.)

Responding to keystrokes

After you’ve set up an event handler, you need to write the function to respond to keystrokes, which is a pretty easy task. Here is the keyListener code (found in keyboard.js):
tmp11224_thumb_thumbtmp11225_thumb_thumb
This code grabs an event object if needed, and then analyzes that object to figure out which key (if any) was pressed. It then calls the moveSprite() function to move the sprite. Here’s the low-down:
1. Event functions have event objects.
Just knowing that an event has occurred isn’t enough. You need to know which key the user pressed. Fortunately, the browsers all have an event object available that tells you what has happened.
2. Many browsers pass the event as a parameter.
When you create an event function, the browser automatically assigns a special parameter to the function. This parameter (normally called e) represents the event. Just make the function with a parameter called e, and most browsers create e automatically.
tmp11226_thumb_thumb
3. Internet Explorer needs a little more help.
IE doesn’t automatically create an event object for you, so you need to specifically create it.
tmp11227_thumb_thumb
4. You can use e to figure out which key the user pressed.
The e object has some nifty properties, including keyCode. This property returns a number that tells you which key the user pressed.
Do a quick search on JavaScript event object to find out other kinds of event tricks. I’m showing the most critical features here, but this is just an introduction to the many interesting things you can do with events.
5. Compare the keycode property of the event object to the keycodes corresponding to keys you’re interested in.
You can figure out the keycodes of any keys on your keyboard, and you can use basic if statements to respond appropriately. (I explain key-codes in the following section.)
tmp11228_thumb_thumb
6. Call appropriate variations of moveSprite.
If the user pressed the left-arrow key, move the sprite to the left. You can use the moveSprite() function defined in movement.js for this.

Deciphering the mystery of keycodes

When you look over the code in the keyListener function, you can see some odd numbers in there. For example, the code that looks for the left arrow key actually compares the e.keyCode to the value 3 7. The big mystery is where all the numbers in the keyListener function (in the previous section) came from.
These numbers are called keycodes. They are numeric representations of the physical keys on the keyboard. Each physical key on the keyboard has a corresponding keycode. Keycodes are mapped to the physical key, which means the keycode corresponding to a key is the same even if the keyboard mapping is changed (to a foreign language or alternate input setting, for example).
How did I know that the left-arrow key corresponds to the keycode 37? It’s pretty simple, really. I just wrote a program to tell me. Figure 8-3 shows readKeys.html in action.
This program reads the keyboard and reports the key codes.
Figure 8-3:
This program reads the keyboard and reports the key codes.
Run readKeys and press a few keys. You can then easily determine what keycode is related to which key. You might also want to look over the code in this format if you’re a little confused; because all the code’s in one place, you might it’s easier to read than the movement examples.
If you use a notebook or an international keyboard, be aware that some of the keycodes can be nonstandard, especially numeric keypad keys. Try to stick to standard keys if you want to ensure that your program works on all keyboards.

Following the Mouse

You can create an event handler that reads the mouse. Figure 8-4 shows such a program.
Now the sprite stays with the mouse.
Figure 8-4:Now the sprite stays with the mouse.

Achieving this effect is actually quite easy when you know how to read the keyboard, because it works in almost exactly the same way.

Looking over the HTML

The code for followMouse.html is simple enough that I kept it in one file.
tmp11231_thumb_thumb

Setting up the HTML

The HTML page is simple. This time I’m letting the mouse take up the entire page. No borders are necessary, because the sprite won’t be able to leave the page. (If the mouse leaves the page, it no longer sends event messages.)
Just create a sprite with an image as normal and be sure to call init() when the body loads.

Initializing the code

The initialization is pretty straightforward:
1. Create a global variable for the sprite.
Define the sprite variable outside any functions so it will be available to all of them.
tmp11232_thumb_thumb
2. Build the sprite in init() .
The init() function is a great place to create the sprite.
tmp11233_thumb_thumb
3. Set up an event handler for mouse motion.
Set up an event handler in init(). This time you’re listening for mouse events, so call this one mouseListener.
tmp11234_thumb_thumb

Building the mouse listener

The mouse listener works much like a keyboard listener. The mouse listener is called whenever the mouse moves, and it examines the event object to determine the mouse’s current position. It then uses that value to place the sprite:
1. Get the event object.
Use the cross-platform technique to get the event object.
tmp11235_thumb_thumb
2. Determine the sprite’s width and height.
The top and left properties will point to the sprite’s top-left corner. It looks more natural to have the mouse in the center of the sprite. To calculate the center, you need the height and width values. Don’t forget to add these values to the local style for the sprite.
tmp11236_thumb_thumb
3. Use e.pageX and e.pageY to get the mouse position.
These properties return the current position of the mouse on the page.
4. Determine x and y under the mouse cursor.
Subtract half of the sprite’s width from the mouse’s x value (e.pageX) so the sprite’s horizontal position is centered on the mouse. Repeat with the y position.
tmp11237_thumb_thumb
5. Move the mouse to the new x and y coordinates.
Use the conversion techniques to move the sprite to the new position.
tmp11238_thumb_thumb
Another fun effect is to have the sprite influenced by the mouse. Don’t make it follow the mouse directly but check to see where the mouse is in relationship with the sprite. Have the sprite move up if the mouse is above the sprite, for example.
Achieving this effect is actually quite easy when you know how to read the keyboard, because it works in almost exactly the same way.

Looking over the HTML

The code for followMouse.html is simple enough that I kept it in one file.
tmp11231_thumb_thumb

Setting up the HTML

The HTML page is simple. This time I’m letting the mouse take up the entire page. No borders are necessary, because the sprite won’t be able to leave the page. (If the mouse leaves the page, it no longer sends event messages.)
Just create a sprite with an image as normal and be sure to call init() when the body loads.

Initializing the code

The initialization is pretty straightforward:
1. Create a global variable for the sprite.
Define the sprite variable outside any functions so it will be available to all of them.
tmp11232_thumb_thumb
2. Build the sprite in init() .
The init() function is a great place to create the sprite.
tmp11233_thumb_thumb
3. Set up an event handler for mouse motion.
Set up an event handler in init(). This time you’re listening for mouse events, so call this one mouseListener.
tmp11234_thumb_thumb

Building the mouse listener

The mouse listener works much like a keyboard listener. The mouse listener is called whenever the mouse moves, and it examines the event object to determine the mouse’s current position. It then uses that value to place the sprite:
1. Get the event object.
Use the cross-platform technique to get the event object.
tmp11235_thumb_thumb
2. Determine the sprite’s width and height.
The top and left properties will point to the sprite’s top-left corner. It looks more natural to have the mouse in the center of the sprite. To calculate the center, you need the height and width values. Don’t forget to add these values to the local style for the sprite.
tmp11236_thumb_thumb
3. Use e.pageX and e.pageY to get the mouse position.
These properties return the current position of the mouse on the page.
4. Determine x and y under the mouse cursor.
Subtract half of the sprite’s width from the mouse’s x value (e.pageX) so the sprite’s horizontal position is centered on the mouse. Repeat with the y position.
tmp11237_thumb_thumb
5. Move the mouse to the new x and y coordinates.
Use the conversion techniques to move the sprite to the new position.
tmp11238_thumb_thumb
Another fun effect is to have the sprite influenced by the mouse. Don’t make it follow the mouse directly but check to see where the mouse is in relationship with the sprite. Have the sprite move up if the mouse is above the sprite, for example.

Automatic Motion

You can make a sprite move automatically by attaching a special timer to the object. Figure 8-5 shows the ball moving autonomously across the page.
Timer.html is surprisingly simple, because it borrows almost everything from other code.
tmp11239_thumb_thumbtmp11240_thumb_thumb
The HTML and CSS are exactly the same as the button.html code. Most of the JavaScript comes from movement.js. The only thing that’s really new is a tiny but critical change in the init() method.
JavaScript contains a very useful function called setlnterval, which takes two parameters:
A function call: Create a string containing a function call including any of its parameters.
A time interval in milliseconds: You can specify an interval in 1,000ths of a second. If the interval is 500, the given function will be called twice per second; 50 milliseconds is 20 calls per second; and so on.
This sprite is moving on its own. (I added the arrow to show motion.)
Figure 8-5:
This sprite is moving on its own. (I added the arrow to show motion.)
You can set the interval at whatever speed you want, but that doesn’t guarantee things will work that fast. If you put complex code in a function and tell the browser to execute it 1,000 times per second, it probably won’t be able to keep up (especially if the user has a slower machine than you do).
The browser calls the specified function at the specified interval. Put any code that you want repeated inside the given function.
Don’t put anything in an interval function that doesn’t have to go there. Because this code happens several times per second, it’s called a critical path, and any wasteful processing here could severely slow down the entire program. Try to make the code in an interval function as clean as possible. (That’s why I created the sprite as a global variable. I didn’t want to recreate the sprite 20 times per second, making my program impossible for slower browsers to handle.)
By using automatically moving objects, you get a chance to play with other kinds of boundary detection. If you want to see how to make something bounce when it hits the edge, look at bounce.html and bounce.js on either of the companion Web sites  along with the other code featured in this chapter.

Image-Swapping Animation

The other kind of animation you can do involves rapidly changing an image. Look at Figure 8-6 to see one frame of an animated figure.
This sprite is kicking!
Figure 8-6:
This sprite is kicking!
Animation is never that easy to show in a still screen shot, so Figure 8-7 shows the sequence of images used to build the kicking sprite.
I used this series of images to build the animation.
Figure 8-7:
I used this series of images to build the animation.
You can use any series of images you want. I got these images from a site called Reiner’s Tilesets (http://reinerstileset.4players.de/ englisch.html). It includes a huge number of sprites, each with several animations. These animations are called Freya.

Preparing the images

You can build your own images, or you can get them from a site like Reiner’s Tilesets. In any case, there are a few things to keep in mind when building image animations:
Keep them small. Larger images will take a long time to download and will not swap as smoothly as small ones. My images are 128 x 128 pixels, which is a good size.
Consider adding transparency. The images from Reiner’s Tilesets have a brown background. I made the background transparent by using my favorite graphics editor (GIMP).
Change the file format. The images came in .bmp format, which is inefficient and doesn’t support transparency. I saved them as .gif images to make them smaller and enable the background transparency.
Consider changing the names. I renamed the images to make the names simpler and to eliminate spaces from the filenames. I called the images kick0 0.gif to kick12.gif.
Put animation images in a subdirectory. With ordinary page images, I often find a subdirectory to be unhelpful. When you start building animations, you can easily have a lot of little images running around. This is a good place for a subdirectory.
Be sure you have the right to use the images. Just because you can use an image doesn’t mean you should. Try to get permission from the owner of the images, cite your source, and host the images on your own server. It’s just good citizenship.

Building the page

The code for animation just uses variations of things you’ve already done: a setlnterval function and some DOM coding.
tmp11244_thumb_thumbtmp11245_thumb_thumb

The HTML is incredibly simple:

1. Set up the body with an init() method.
As usual, the body’s onclick event calls an init() method to start things up.
2. Create a sprite div.
Build a div named sprite. Because you won’t be changing the position of this div (yet), you don’t need to worry about the local style.
3. Name the img.
In this program, you want to animate the img inside the div, so you need to give it an id.
Building the global variables
The JavaScript code isn’t too difficult, but it requires a little bit of thought:
1. Create an array of image names.
You have a list of images to work with. The easiest way to support this is with an array of image names. Each element of the array is the filename of an image. Put them in the order you want the animation frames to be shown.
tmp11246_thumb_thumb
2. Build a frame variable to hold the current frame number.
Because this animation has 12 frames, the frame variable will go from 0
to 11.
tmp11247_thumb_thumb
3. Set up spritelmage.
This variable will be a reference to the img tag inside the sprite tag.
tmp11248_thumb_thumb

Setting up the interval

The init() function attaches the spritelmage variable to the image object and sets up the animate() method to run ten times per second.
tmp11249_thumb_thumb

Animating the sprite

The actual animation happens in the (you guessed it) animate() function. The function is straightforward:
1. Increment the frame counter.
Add one to the frame variable.
tmp11250_thumb_thumb
2. Check for bounds.
Any time you change a variable, you should consider whether it could go out of bounds. I’m using frame as an index in the imgList array, so I check to see that frame is always less than the length of imgList.
tmp11251_thumb_thumb
3. Reset the frame if necessary.
If the frame counter gets too high, reset it to 0 and start the animation over.
4. Copy the image filename from the array to the src property of the
spritelmage object.
This step causes the given file to display.
tmp11252_thumb_thumb

Improving the animation with preloading

When you run the image swap program, you will get some delays on the first pass as all the images load. (Making the images smaller and saving them in the .gif or .png format helps with the delays.) Most browsers store images locally, so the images will animate smoothly after the first pass.
If you want smoother animation, you can use a technique called preloading. This causes all the images to load before the animation begins. The Preload.html file makes a few changes to preload the image. (I don’t show a figure because it looks just like imageswap to the user.)

There are no changes in the HTML code. The only changes are in the JavaScript code:

tmp11253_thumb_thumb

Here’s how the preloading works:

1. Change the array name to imgFiles.
This distinction is subtle but important: The array doesn’t represent actual images, but the filenames of the images. You need to create another array to hold the actual image data.
2. Create an array of images.
JavaScript has a data type designed specifically for holding image data. The images array holds the actual image data (not just filenames, but the actual pictures). The images array should be global.
3. Create a function to populate the images array.
The loadlmages() function creates the array of image data. Call
loadImages() from init().
4. Build a loop that steps through each element of the imgFiles array.
You build an image object to correspond to each filename, so the length of the two arrays needs to be the same.
5. Build a new image object for each filename.
Use the new Image() construct to build an image object representing the image data associated with a particular file.
6. Attach that image object to the images() array.
This array now contains all the image data.
7. Modify animate() to read from the images() array.
The animate() function now reads from the images() array. Because the image data has been preloaded into the array, it should display more smoothly.
Preloading images doesn’t make the animation faster. It just delays the animation until all the images are loaded into the cache, making it appear smoother. Some browsers still play the animation before the cache has finished loading, but the technique still has benefits.
Even if you don’t like animation, these techniques can be useful. You can use the setlnterval() technique for any kind of repetitive code you might want, including the dynamic display of menus or other page elements. In fact, before CSS became the preferred technique, most dynamic menus used JavaScript animation.

Working with Compound Images

Another common approach to image-swapping animation is to combine all images to a single graphic file and use CSS techniques to display only one part of that image. Figure 8-8 shows you what I mean.
The chopper compound image.
Figure 8-8:
The chopper compound image.
This image file contains several images of a helicopter. Each subimage shows a different position of main rotor and tail rotor. The compound.html page shows this image, but it shows only one segment of the image at a time. The part of the image that’s displayed is changed rapidly to give the appearance of animation. This technique has some advantages:
A single image loads more efficiently than a number of separate images.
The entire image loads at once, eliminating the lag associated with multiple images
You can combine very complex images with multiple animations in this way.
The completed HTML looks like Figure 8-9 (except, of course, you can see the helicopter’s rotors spinning on the real page).
The image is moved within the div to give the animation effect.
Figure 8-9:
The image is moved within the div to give the animation effect.

Preparing the image

Preparing an image to be used in this way does require some care. You must plan to ensure it’s easy to animate the image:
Combine all images to a single file. Use an image-editing tool, such as Gimp or Photoshop.
‘ Make sure all subimages are the same size. Your life will be easier if all the images are a consistent size. All the chopper images are 64 pixels tall and 132 pixels wide.
‘ Make all subimages the same distance apart. The images are all 132 pixels apart.
‘ Arrange images in rows or columns. If you have a single animation, place it in a row or column to simplify your math. You can combine more images for more complex animations (for example, a sequence of walk cycles in each direction.
The particular image used in this example is from Ari’s SpriteLib (www. flyingyogi.com/fun/spritelib.html), an excellent resource of open-source game graphics. I modified the image slightly for use in this example.

Setting up the HTML and CSS

As with many animation examples, the HTML code is rather minimal. All that’s necessary is a div with an id attribute:
tmp11256_thumb_thumb
As you can see, the div doesn’t even have an image in it. The image is placed and manipulated through CSS with the background-image property.

The CSS is likewise quite simple:

tmp11257_thumb_thumb

The CSS does a number of important tasks:

1. Apply the image.
The entire image is applied as the background image of the div.
2. Resize the div.
The div size is adjusted to reflect the size of a single subimage. If you look at the HTML at this point, the div looks like an ordinary image, showing only the first sub-image of the chopper.
3. Set the initial background position.
Only the first chopper is showing, but the entire image (with four choppers) is attached to the div. I use CSS to move the image so different frames of the animation appear in the div’s visible space. The initial position is 0px 0px, meaning that the upper-left corner of the image is aligned with the upper-left corner of the div.
This entire helicopter animation might seem like a lot of unnecessary grief. You might ask why I bother when I could just use an animated GIF image. The answer is control. I could use those alternatives, and sometimes they’d be a better choice. However, if you know how to control the animation directly through JavaScript, you can do things you can’t do otherwise, like change the animation speed or freeze on a particular frame.

Writing the JavaScript

The general strategy is to run an ordinary animation loop but to change the background position of the div every frame so it displays a different frame of the animation. The second frame of the animation occurs at pixel 132, so if you move the background image to the left by 132px, you see the second frame. I stored the position necessary to display each frame in an array called offset. Much of this program looks like the previous image-swapping code.

Setting up global variables

Begin with some global variables that will be used throughout the application:
tmp11258_thumb_thumb
1. Create an offsetList array.
This array holds the coordinates necessary to display each image in the list. Use an image editor to check the positions.
2. Create a frame variable.
This integer describes which frame of the animation is currently showing. It will be used as an array index to display the various animation frames.
3. Create a variable to hold the div.
The chopper variable will hold a reference to the div. Changing the style of the chopper variable will change the visible image.

Building an init() function

The initialization function sets up the animation:
tmp11259_thumb_thumb
The init() function is called by the body onload event. It has two jobs:
1. Create a reference to the chopper div.
Remember, the div doesn’t exist until the body has finished loading, so you must populate the chopper variable in a function. The init() function is a perfect place for this kind of work.
2. Use setlnterval() to create an animation loop.
The program calls the animate() function every 100 milliseconds, or ten times per second.

Animating the sprite

The actual animation is easier than the preparation.
tmp11260_thumb_thumb

To make the animation finally work, follow these steps:

1. Increment the frame counter.
This step indicates that you’re going to a new frame.
2. Check that the frame is within bounds.
The frame variable will be used as an index to the offsetList array, so you need to ensure that it’s smaller than the length of the array. If it’s too big, you can just reset it to 0.
3. Create an offset value.
The offset value is generated from the offsetList array. Note that the array contains only the x value. Concatenate this with “px 0px” to create an offset in the legal format for CSS. (Look at the original CSS for background-position to see the format.)
4. Apply the offset to the chopper variable.
Use the backgroundPosition attribute of the style attribute to dynamically change the background image’s position.

Movement and Swapping

You can combine motion effects with image-swapping to have an image move around on the screen with animated motion. Figure 8-10 tries to show this effect, but you need to use a browser to really see it.
Making this program requires nothing at all new. It’s just a combination of the techniques used throughout this chapter. Figure 8-11 shows the list of images used to make Freya run. (I added the arrow again just so you can see how the movement works.)

Building the HTML framework

The HTML is (as usual) pretty minimal here:
tmp11261_thumb_thumbtmp11262_thumb_thumbRun, Freya, Run!
Figure 8-10:
Run, Freya, Run!
These are the running images from Reiner's Tilesets.
Figure 8-11:
These are the running images from Reiner’s Tilesets.
When you want to create a moving image-swap animation, follow these steps:
1. Import the script.
You can build the script locally (as I did in the last example), but any time the script gets complex, it might be better in an external file.
2. Call an init() method.
Most animation requires an init() method called from body. onload() , and this animation is no exception.
3. Name the sprite.
The sprite is a div that will move, so it needs absolute position, top, and left properties all defined as local styles.
4. Name the image.
You also want to animate the image inside the sprite. The only property you’ll change here is the src, so no local styles are necessary here.

Building the code

The JavaScript code is familiar because all the elements can be borrowed from previous programs. Here’s the code for run.js (used by run.html) in its entirety.
tmp11265_thumb_thumbtmp11266_thumb_thumb

Defining global variables

You have a few global variables in the code from the previous section:
frame :The frame number. It is an integer from 0 to 11 that serves as the index for the imgList array.
imgList: An array of filenames with the animation images.
sprite: The div that will be moved around the screen.
spritelmage: The img element of sprite. This is the image that will be swapped.
MAX_X: A constant holding the maximum value of X. In this program, I’m moving only in one direction, so the only boundary I’m worried about is MAX_X. If the sprite moved in other directions, I’d add some other constants for the other boundary conditions.

Initializing your data

The init() function performs its normal tasks: setting up sprite variables and calling the animate() function on an interval.
tmp11267_thumb_thumb
When you move and swap images, sometimes you’ll have to adjust the animation interval and the distance traveled each frame so the animation looks right. Otherwise the sprite might seem to skate rather than run.

Animating the image

I really have two kinds of animation happening at once, so in the grand tradition of encapsulation, the animate() function passes off its job to two other functions:
tmp11268_thumb_thumb

Updating the image

The updatelmage() function handles the image-swapping duties:
tmp11269_thumb_thumb

Moving the sprite

The sprite is moved in the updatePosition() function:
tmp11270_thumb_thumb
I know what you’re thinking: You could use this stuff to make a really cool game. It’s true. You can make games with JavaScript, but you’ll eventually run into JavaScript’s design limitations. I prefer Flash and Python as languages to do game development. Now that I mention it, I’ve written other  topics on exactly these topics: Flash Game Programming For topic and Game Programming: The L Line. See you there!

Next post:

Previous post: