This is not a tutorial on learning how to animate — for that, I recommend Richard Williams’s excellent book The Animator’s Survival Kit.
This tutorial is about what to do with those animations. How do you get them inside the game? What code do you need to make a character play one animation when walking left, another when walking right, and yet another when standing still?
There are essentially two ways to handle this. Since the decision for which to use will usually lie in the hands of the game’s artist, I don’t want to say “this way is better than that way, so I’ll only show you how do do it this way”. The “correct” way is really whichever lets the animator do his job fastest, so I’ll explain both methods in separate blog posts.
The first method, which I call the “divided timeline” approach, uses the timeline very heavily, with labels and even code(!) on frames. Let’s see how it’s done.
I call the second method the “state MovieClips” approach, and I explain that in a later post. Click here to read it.
Rather than create a whole new game to use as a demonstration, I’m going to add animations to the game I made in my avoider game tutorial. If you followed that tutorial, you should be able to apply this directly to the game you created. If not, don’t worry — you can, of course, use this in your own games, but you might like to download the zip file of the game I made, to make it easier to follow.
Animation 101
In case you’ve never used Flash to animate a symbol before, I’ll quickly run through the steps to give the Enemy movie clip a looping animation. If you’re familiar with all this, you can just skim this section.
Open the FLA, and double-click the Enemy symbol in the Library to go into editing mode. Your screen should look something like this, although hopefully less cramped:

(This is in Flash CS3, by the way. I hear the animation system got revamped in Flash CS4, so this might not apply — please leave a comment below if that’s the case.)
Flash animation works a bit like a flickbook; basically, it just plays a bunch of images in sequence. Sure, you can do much more complicated things than that, but at its core that’s all it is.
To add a new image to this sequence, right-click the first empty frame on the timeline and select Insert Keyframe. Empty frame? Timeline? Check out the image below to see what I mean:

This copies the image from the first frame into the second. Modify this new image in some way. You could stretch it, rotate it, change the colour, redraw it… whatever! Here’s mine, slightly squashed:

Repeat this as many times as you like to get the animation you desire. Remember to make the image on the last frame look almost identical to the image on the first frame, or it’ll be “jumpy” when it loops. It might help to know that you can copy a frame through the right-click menu, and paste it anywhere on the timeline in the same way.
Once you’re ready, run the game as usual:
As you can see, Flash automatically loops the animation.
We can slow down the speed of the animations by clicking Modify > Document and changing the frame rate. In the example above, I had the frame rate set at 24fps (frames per second). Below, I’ve changed it to 12fps:
The game feels a lot jerkier, because as well as slowing down the animations, lowering the fps also causes the screen to be redrawn (re-rendered, or refreshed) less frequently. However, because all our game logic is controlled by a timer, rather than by the frame rate, the speed at which the enemies and the avatar move does not change.
(Note: it’s possible to affect the speed of the avatar by increasing the frame rate so much that Flash has to work very hard to keep up, and thus slows everything down. Watch out for this.)
So, those are the basics. Check out the great tutorials on Tutorio.us for more.
Dividing the Timeline
You could do the same for the avatar, but I think we can do better. How about having five different animations: one for movement in each direction, and one for when it’s standing still?
First, double-click the Avatar in the Library to get into editing mode again. Just as before, we need to make a looping animation to play when the avatar is standing still. I’ve done the same kind of animation as for the enemies, to keep things simple:
Next, let’s add an animation to be played while the player is moving right.
Create a blank keyframe just after the “standing still” animation by right-clicking the first empty frame on the timeline and selecting Insert Blank Keyframe.
The “moving right” animation needs to be added to the end of the “standing still” animation, but separated by this new blank keyframe. So, if your “standing still” animation takes four frames, and you want your “moving right” animation to take another four, then the blank keyframe should be on frame 5, and “moving right” should take frames 6, 7, 8 and 9.
My “moving right” animation is identical to my “standing still” animation, except all the frames have been rotated 30 degrees clockwise:

And my timeline looks like this:

If you run your game now, then, of course, it’ll look a mess, with the avatar switching between standing still and looking like it’s moving to the right, no matter whether or not it actually is moving. We need to tidy this up.
First, let’s get the “standing still” animation looping correctly. On the timeline, right-click the blank keyframe that separates the two animations select Actions. A panel for entering code will appear. Enter the following:
gotoAndPlay(1);
Close this panel. You’ll notice that the frame you just edited on the timeline will have a little “a” on it. This stands for “actions”, as in ActionScript.
Run the game, and you’ll see the animation just plays the first four frames. As soon as the animation reaches the blank keyframe, the line gotoAndPlay(1) is run, and this send the animation back to the first frame.
Labels
We can make things more intuitive by labelling our frames. Left-click the first frame in the timeline, and enter StandingStill in the box in the Properties panel:

In the same way, label the first frame of your “moving right” animation as MovingRight. You’ll see little red flags appear in the timeline to let you know that these frames have labels:

Create a new blank keyframe after the “moving right” animation, right-click it, and select “Actions”. We’re going to make this one loop as well.
We could just type:
gotoAndPlay(6);
But what if we decide to add more frames to the “standing still” animation later? It’d screw things up. However, because we labelled the first frame of the “moving right” animation, we can just type:
gotoAndPlay("MovingRight");
Make sure you use speech marks, and that the text matches your label exactly, right down to the capital letters.
Now we need to write some code to tell the game to actually play this animation when the player moves to the right. Open AvoiderGame.as and find this block of code:
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | if ( downKeyIsBeingPressed ) { avatar.moveABit( 0, 1 ); } else if ( upKeyIsBeingPressed ) { avatar.moveABit( 0, -1 ); } else if ( leftKeyIsBeingPressed ) { avatar.moveABit( -1, 0 ); } else if ( rightKeyIsBeingPressed ) { avatar.moveABit( 1, 0 ); } |
You can probably guess what we need to do. It’s a small change:
154 155 156 157 158 | else if ( rightKeyIsBeingPressed ) { avatar.gotoAndPlay("MovingRight"); avatar.moveABit( 1, 0 ); } |
Save and run the game:
As you can see, the avatar plays the correct animation when the right arrow is pressed… but it doesn’t stop playing it when it’s released. Can you see why?
It’s pretty easy to solve:
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | if ( downKeyIsBeingPressed ) { avatar.moveABit( 0, 1 ); } else if ( upKeyIsBeingPressed ) { avatar.moveABit( 0, -1 ); } else if ( leftKeyIsBeingPressed ) { avatar.moveABit( -1, 0 ); } else if ( rightKeyIsBeingPressed ) { avatar.gotoAndPlay("MovingRight"); avatar.moveABit( 1, 0 ); } else { //player is not pressing any keys at all avatar.gotoAndPlay("StandingStill"); } |
(Lines 159-162 are new, there.)
Test the game:
It works, more or less. Except… the animations aren’t actually playing, are they? Only the first frame of each is being shown. Have a think about why this is; in the meantime, let’s get the other three animations in there.
Just as before, here’s the process:
- Add new animation frames to Avatar’s timeline.
- Give the first frame an appropriate label.
- Add a new blank keyframe.
- Bring up the Actions panel for that keyframe.
- Enter,
gotoAndPlay("Label"); - Add
avatar.gotoAndPlay("Label");to the correct place in AvoiderGame.as.
All done? Great! Test it out:
I’ll admit, my animations for moving up and down look pretty weird :S
Playing the Whole Animation
Now we need to sort out that bug where it only plays the first frame of the animation.
Did you figure out why it was happening? It’s because we call gotoAndPlay("MovingRight") (or whichever direction) every tick. If the player holds down the right arrow key for ten frames in a row, then each frame we’re telling Flash to play the animation starting from the frame labelled MovingRight.
To fix this, we need to know which animation is currently playing, so that we can decide not to interfere if it’s the one we want. In other words, we want our code to work like this:
else if ( rightKeyIsBeingPressed ) { if ( avatar.currentAnimationState != "MovingRight" ) { avatar.gotoAndPlay("MovingRight"); avatar.currentAnimationState = "MovingRight"; } avatar.moveABit( 1, 0 ); } |
(!= means “is not equal to”, by the way.)
I’ve used the word state here to denote the type of animation that’s currently playing.
We’ll need to add a new public variable to the Avatar, so open Avatar.as. I’ve copied my entire AS file below, as it’s so short:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | package { import flash.display.MovieClip; public class Avatar extends MovieClip { public var currentAnimationState:String; public function Avatar() { currentAnimationState = "StandingStill"; } public function moveABit( xDistance:Number, yDistance:Number ):void { var baseSpeed:Number = 3; x += ( xDistance * baseSpeed ); y += ( yDistance * baseSpeed ); } } } |
(The new lines are 6 and 10.)
Now all we need to do is work this into AvoiderGame.as, as in the example above:
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | if ( downKeyIsBeingPressed ) { if ( avatar.currentAnimationState != "MovingDown" ) { avatar.gotoAndPlay("MovingDown"); avatar.currentAnimationState = "MovingDown"; } avatar.moveABit( 0, 1 ); } else if ( upKeyIsBeingPressed ) { if ( avatar.currentAnimationState != "MovingUp" ) { avatar.gotoAndPlay("MovingUp"); avatar.currentAnimationState = "MovingUp"; } avatar.moveABit( 0, -1 ); } else if ( leftKeyIsBeingPressed ) { if ( avatar.currentAnimationState != "MovingLeft" ) { avatar.gotoAndPlay("MovingLeft"); avatar.currentAnimationState = "MovingLeft"; } avatar.moveABit( -1, 0 ); } else if ( rightKeyIsBeingPressed ) { if ( avatar.currentAnimationState != "MovingRight" ) { avatar.gotoAndPlay("MovingRight"); avatar.currentAnimationState = "MovingRight"; } avatar.moveABit( 1, 0 ); } else { //player is not pressing any keys at all if ( avatar.currentAnimationState != "StandingStill" ) { avatar.gotoAndPlay("StandingStill"); avatar.currentAnimationState = "StandingStill"; } } |
Yikes, that’s messy. Does it work?
Yes!
Wrapping Up
So that’s the “divided timeline” approach. Click here to read the next part of this mini-series, where we’ll look at the other approach: using one movie clip per animation state.
Before then, why not see if you can figure out a way to tidy up that messy code in AvoiderGame.as?
The zip file with all the files I modified is available here.








{ 2 trackbacks }
{ 14 comments… read them below or add one }
Are you by any chance related to Richard Williams?
Awesome tutorial dude!
Thanks Tim!
Haha Mushyrulez, I nearly wrote “(no relation)” after his name
Nah, not as far as I know at least.
Good job on the tutorial!
I’m often try to use tweening as much as possible though and reduce frame by frame animation
. For smooth purpose.
Cheers, Rosedragon, and good point on the tweens
Your missing something… Enemy animation change based on which direction he moves!, A little tricky… well until you play around with “current label”. This is a small chunk of my game, to get you started, especially if anyone needs the enemies to switch animations. Although as always, there is a better way to do it.
if (enemy.base.hitTestObject(wall)) { if (enemy.front.hitTestObject(wall)) { enemy.x-= xVel; enemy.y-= yVel; enemy.lockTarget.width = 0; } if (enemy.currentLabel == "walk") { enemy.gotoAndPlay("sit"); if (enemy.Left.hitTestObject(wall)) { enemy.rotation += 1.8; } else if (enemy.Right.hitTestObject(wall)) { enemy.rotation -= 1.8; } } }yuck, sorry the code is hard to read, intresting that the last of it was put in a scrolling box.. hm… how would I “box” the code next time?
Nice one Kevin. Hey, you could use the rotation to affect the animation too, so an enemy walking upwards would only show the back of his head.
Oh, WordPress comments seem to do that with code, it’s really irritating. To create your own code box you just use “pre” tags: <pre> before the code and </pre> after it.
Alright, I messed up again. I’m trying to make the random enemies have a different animation decided randomly. I coded something like this, but I can’t seem to figure out where or how to call this function properly. It may even be in my naming. Any ideas. Here is my snippet of code
var randomAnimate = Math.floor(Math.random()*4); if (randomAnimate == 1) { enemy.gotoAndPlay("ClockwiseCoal"); } else { enemy.gotoAndPlay("CounterClockwiseCoal"); }I plan to have 3 animations, but I haven’t done them because I wanted to get it working first. I tried to call a function when the enemy was created, but I kept getting “TypeError: Error #1009: Cannot access a property or method of a null object reference. at AvoiderGame/onTick() at flash.utils::Timer/_timerDispatch() at flash.utils::Timer/tick()”
Hey Grey.
Where exactly are you calling it from at the minute? I know you said “when the enemy was created” but if you could provide a snippet of the surrounding code that’d be great.
If it’s somewhere here:
var newEnemy:Enemy = new Enemy( randomX, -15 ); army.push( newEnemy ); addChild( newEnemy );…then I think it’s just a simple typo — you have written
enemy.gotoAndPlay()when it should benewEnemy.gotoAndPlay(). But that’s just a guessOnce again I’ve made a silly little mistake. Thanks for the easy fix. One of these days I’ll make a non-typo mistake.
thanks again. Good catch.
No problem
The silly mistakes are often the hardest to spot, and the most annoying to find.
What if my Avatar is a character with a walkcycle of several layers and frames packaged into a MovieClip. How can I get him to play only on keyPresses? I have done it by writing code directly into the fla. file when I gave it an instance name, but I can’t figure out how to do it in classes.
Hey Joe,
If you want to avoid writing code directly into the FLA file (i.e. on the timeline) you can use State MovieClips. That’d give you an easy way to bundle up all your layers into a single simple object as well.
Let me know how you get on with that