JavaScript Animation That Works (Part 2 of 4)

In the last post, we introduced the idea of spriting, an easy way to animate in JavaScript that works in all browsers. We also walked through how to set up the sprite as a background image for a div and then use a line of JavaScript to change the background position to make it appear as if the image has moved.

In this post, we will use this technique to animate both running and jumping motions. In order to create the animation, we will need to quickly change the background position at a regular interval. Take a look again at the sprite we are using.

javascript-spriting-j

Meet J, the mascot for my company, Joust Multimedia.

In our example, we have ten total images: one of J standing facing right, three of J running to the right and one of J jumping while facing right (with the same number of each frame facing left). Let's start with making him run to the right. In order to make our image look like it is running, we will need to do two things: change the sprite to a different image and move the div towards the right.


Running to the Right Animation

We certainly won't want to be stuck clicking different buttons to cycle through the sprites, so we will need to create some functions that do this automatically.

For our running function, we want to:

  1. Move the div towards the right slightly
  2. Move to the next frame of animation
  3. Pause for a fraction of a second (to preserve the "persistence of vision" illusion)
  4. Loop the function again

Fortunately, there is an easy way to loop with functions. A native command in JavaScript called setTimeout will allow us to create a timed delay, after which we will call the function again (from inside the function).

So now we have a function that will call itself again five times a second (which will be fast enough to create animation for our purposes). Remember here that browsers are not terribly accurate with their timers. You can specify timing to the millisecond, but that doesn't mean your script will run at that timing exactly!

Our next problem to tackle is how is our function going to know which sprite to change to? In our example, we will need to cycle back and forth through our three images (to have four total frames of animation). To do this, we are going to pass our function a bit of information to tell it which slide to switch to. Once in the function, we will do a test that will check which slide we should be on, then switch the background position to the correct sprite. When we call the function again, we will pass the next slide as the argument.

And now when we call the function for the first time, we will need to make sure we pass the starting slide.

Similarly, to move our div to the right slightly, we can pass the initial left attribute of the div, then move the div slightly each time the function is called.

And when we initially call the function, we need to make sure we pass the current left position of our div.


Stopping the Animation

So, now we have a function that, when called, will animate J to run to the right. Unfortunately, we have no way to stop it. First of all, we will need to make the function stop calling itself if J runs to the edge of our stage. To do that, every time the function runs, we will check an if statement to see if J has room to keep running. If so, we will run the function like normal. If not, we will stop calling the function and return him to the standing sprite.

Finally, we will want to have a way to stop the function, when needed. We can set the setTimeout() command to a variable, then stop it with the clearTimeout() command. In order to do this, we will need to declare that variable outside of the function, so that we will be able to refer to it later. For now, we will declare it as a global variable. This is terrible coding practice, but we will correct this in the next post. This is what our function looks like.

And we can create another function to stop the running timer and return the sprite to the standing image.


Running to the Left Animation

Now by borrowing the code from our run_right function, we can create another function to make a run_left function, with just a few modifications.


Jumping Animation

Finally, we need to create a jump function. We will pass two arguments to this function, one that will track whether the div is currently moving up or down and another that will track the current top attribute of the div. Between the two, we will determine which direction the div needs to move next, and how far (we will move the div less distance near the arc of the jump to simulate acceleration with gravity).

Now we can put all four of our functions into buttons and have a working prototype of a running and jumping animation! Please check out the source code for this page with comments and download the sprite sheet that I used, if you'd like.


Conclusion

Now, although we have a working prototype here, you may notice it is a little buggy. When you click on more than one button at a time, the script will try to run both at once. Or, if you click the jump button again on the way down, J will continue to fall forever. Also, as I mentioned earlier, we have global variables in our script, which means it might be difficult to add this code into an existing page without crashing other JavaScript (which is also why I didn't try to run this code within this blog page). In our next post, we will clean up all of these bugs and talk about the concept of encapsulation and why it is important to write good code in the real world.

Tags:

Comments

Related Articles