Learn ActionScript 3 by Following this Simple Avoider Game Tutorial

by Michael James Williams on September 17, 2008 · 385 comments

in Avoider Game Base,Tutorial

(This tutorial is also available in Spanish, Polish, Italian, French, Turkish, and Russian. I’ve also started re-writing it for HTML5.)

This tutorial’s getting a little old now. It still works, but if you want a more up-to-date guide to learning Flash, I recommend reading my post How to Learn Flash and AS3 for Game Development.

Introduction

A lot of Flash developers find the jump from ActionScript 2 to ActionScript 3 very daunting. Conversely, a lot of programmers of other languages find ActionScript 3 quite intuitive, but hate ActionScript 2! This tutorial does not require you to know AS2, or even have used Flash before. You’ll find it easier if you already know the basics of some programming language, like variables, if statements, loops, and functions, but don’t worry if that’s not the case. I will be pointing out some of the major differences between AS2 and AS3 for the benefit of those Flash developers making the switch, but I’m not going to focus on these changes.

Frozen Haddock has been kind enough to let me rewrite his ActionScript 2 Avoiding Game Tutorial in ActionScript 3. Thanks, Frozen Haddock! This is not a direct port of his tutorial, however. I’ll be redesigning the code to follow good AS3 practices, which means:

  • One frame
  • One layer
  • No items on the Stage
  • No code in the timeline
  • No code in any symbols

(If you’ve never used Flash to create a game before, the above will probably mean nothing to you. Trust me, that’s a good thing!)

These rules might have to be bent a little when it comes to adding a preloader. We’ll cross that bridge when we come to it.

We’ll also be using classes and events and OOP and all sorts of nice programmer things. But I’m getting ahead of myself. In this part of the tutorial, we’ll just be setting everything up and putting in some very basic game mechanics. To see just how basic, check it out by clicking the image below:

click here to see what we'll be working towards

And by the end of this 12-part tutorial, it’ll look like this, with keyboard controls, multiple levels, sounds, and more:

screenshot

Setup

Let’s start off simple. Boot up your copy of Adobe Flash CS3 (or later, if you’re reading this from the future) and select File > New > Flash File (ActionScript 3.0).

Click File > Save and create a new folder somewhere where you can store all the game’s files. I recommend using your name or initials in the folder’s name as this will make it easier to share with other people later. For reference, I’m calling mine AvoiderGame-MJW. Create a new folder, inside this folder, called Classes. Finally, enter a name for your FLA file (I used AvoiderGame-MJW.fla) and save it — in the main folder, not the Classes folder.

screenshot

There are some default settings we need to alter before we can start on the game proper. Click File > Publish Settings. Click the Flash tab, if it’s not already selected, then click the Settings button next to the ActionScript Version drop-down list:

screenshot

Click the little plus icon above the Classpaths box, and type ./Classes/ in the textbox that appears. This tells Flash that we are going to store the code that we write in the Classes folder we made earlier, so it should check in there if it can’t find any code that it needs.

screenshot

Also, tick the box marked, “Automatically declare stage instances”, if it’s not already ticked.

Next we’ll alter the properties of the game itself. Click Modify > Document and set it up however you like. Frozen Haddock gave his a size of 300 by 300 pixels, and a grey background. I’ve stuck with the grey, but gone for the oldschool-TV-ratio dimensions of 400 by 300 pixels. You can always change this later, so don’t fret too much over it. I do recommend sticking with a frame rate of 24 fps, though. Here’s what I did:

screenshot

OK, that’s the dull setup out of the way. Let’s create our enemy!

Creating the Enemy

The enemy is the object that you, as a player, will have to avoid. (Hence, Avoider Game.) Let’s draw it before giving it life. Click Insert > New Symbol and in the box that appears, give it a Name of Enemy (with a capital E!) and a Type of Movie Clip (in case we want to animate it later). Click OK. The Library will now show your new Enemy object:

screenshot

If you can’t see a Library, make sure Window > Library is checked. By default you will be automatically editing the Enemy — you can tell what you’re editing by the bar over the editing window:

screenshot

If you’re not editing the Enemy for some reason, just double-click it in the Library (or right-click it and select Edit). Draw your Enemy. Frozen Haddock picked a smiley face for his bad guy. Who knows why? Maybe it’s got something to do with those blasted banner adverts. I’m going to do the same. You can make anything you want, but I’m going to assume that we’re all using a roughly circular Enemy, so bear in mind that if you draw a stickman, some parts of this tutorial won’t apply to you. Also, if you’re not used to the Flash drawing environment, it can be a little unintuitive. I recommend this quick drawing tutorial if that applies to you. Here’s my guy:

screenshot screenshot screenshot screenshot

Pretty awesome. There’s a bit of a problem though. You see that little black crosshair with the white background? That’s called the registration point, and when we start writing code to say, “put the Enemy at such-and-such a position”, it’s this point that Flash is going to actually place at that position. (It’s hard to explain in words; later on this will become much clearer.) For this reason, I’m going to move the face around so that the registration point is dead centre. Here’s how to do it:

First, make sure you’re editing your Enemy, and then select everything (click Edit > Select All). A crosshatch pattern will appear:

screenshot

Now, group everything together by clicking Modify > Group Together. A blue box will appear. If you now click and drag anything inside that box, the entire enemy will move as one. (If you had tried this before, you would have ended up dragging his eye out.)

screenshot

Go to the Align panel. If you can’t see it, make sure Window > Align is checked. With the Enemy still selected (i.e., with the blue box still around it), make sure the To stage button is in, and click the two central Align buttons:

screenshot

Now that we’ve finished with the Enemy’s design, we can get out of editing mode. Click Scene 1 on the bar above the editing box. This would be a great time to save our work, so hit File > Save.

The Enemy’s Instructions

So far, nothing we’ve done has been significantly different from what we would have done in any previous version of Flash. That’s about to change. It’s time to start writing code to control the Enemy’s behaviour. As I mentioned at the start, this code is not going to go in either the timeline or the Actions of the Enemy symbol. Instead, it’s going to be kept in an external file. There are a number of benefits to this:

  • The code is completely separate from the artwork, so you can give your artist the FLA file without having to give them the source code.
  • Likewise, you can give a programmer parts of the code without having to send them all your artwork and sounds — or even the rest of the code.
  • If you have a number of programmers each working on separate parts of the code, it’s much easier to put it all back together later.

Click File > New and select ActionScript File. A blank text-editing window will appear. Immediately save the file, as Enemy.as, in the Classes folder you created earlier. This file is going to contain the class — a programming template — for our antagonistic smiley faces.

It’s around this point in an AS3 tutorial that most AS2 programmers start to complain about how much harder it is to use AS3, because there’s so much more that has to be written just to get an object to do something. Please bear with me, and you will see that, although there are indeed more lines of code needed to set this up, they aren’t very difficult to understand, and the approach we take in writing them will really pay off in the long run.

Begin by typing the following:

?View Code ACTIONSCRIPT3
1
2
3
4
package 
{
 
}

The package keyword simply says that everything between the next pair of curly braces is part of a single… well, package. In this case, everything in this package concerns the Enemy object.

As part of this package (so, between the curly brackets), we need to define the Enemy’s class — the template that specifies what it can do, and what we can do with it:

?View Code ACTIONSCRIPT3
1
2
3
4
5
6
7
package 
{
	public class Enemy extends MovieClip 
	{
 
	}
}

Let’s examine this bit by bit:

  • class Enemy — “everything between the next pair of curly brackets makes up the Enemy class.”
  • public — “this class can be accessed by any other piece of code that knows about it.” The alternative would be internal, meaning that only code inside the same package could access this class.
  • extends MovieClip — “I can do anything a MovieClip class can do — and more besides.” So, for example, since we can write code that makes a MovieClip move to the next frame of its animation, we can do the same with an Enemy (or at least we could, if it contained more than one frame). On top of that, we can give this Enemy an HP count (say) which a MovieClip doesn’t have, thus extending the functionality.

The thing is, even though MovieClip is such an important and frequently-used class of object, Flash still has to be told where it is. So, we write in line 3, below:

?View Code ACTIONSCRIPT3
1
2
3
4
5
6
7
8
package 
{
	import flash.display.MovieClip;
	public class Enemy extends MovieClip 
	{
 
	}
}

Finally, the Enemy class needs what’s known as a constructor function. This is just a function that runs whenever a new Enemy is created. All constructor functions must have the same name as the class they belong to, so:

?View Code ACTIONSCRIPT3
1
2
3
4
5
6
7
8
9
10
11
package 
{
	import flash.display.MovieClip;
	public class Enemy extends MovieClip 
	{
		public function Enemy() 
		{
 
		}
	}
}

There’s that word public again. Note that the Enemy function has an empty pair of parenthesis directly after it; more on that later.

So now we have our Enemy class set up, we need to link it to our Enemy graphic. Save the AS file and go back to the FLA file (it’ll be on the tab bar at the top of the window, or in the Window menu, assuming you haven’t closed it). Right click the Enemy in the Library, and select Properties. Click the Advanced button, if it’s there, to show the Linkage panel. Check the Export for ActionScript box, and make sure that the Class reads “Enemy”. If everything’s linked up fine, then clicking the little pencil icon should open up the Enemy class that we were just working on.

screenshot

Click OK to close the Properties box.

Now we need to code in the Enemy’s actual behaviour. What does it need to do? At this point, all we need it to do is:

  • Appear above the top of the screen when it’s created
  • Keep moving downward from that time onward

We already have a space to put code that needs to execute upon the creation of the Enemy — the constructor function. So:

?View Code ACTIONSCRIPT3
1
2
3
4
5
6
7
8
9
10
11
12
package
{
	import flash.display.MovieClip;
	public class Enemy extends MovieClip
	{
		public function Enemy()
		{
			x = 100;
			y = 0;			
		}
	}
}

Since MovieClips have x and y properties, so does our Enemy class.

Those of you familiar with Cartesian coordinates are probably saying, “whoa, Michael! I thought we wanted the Enemy to appear at the top of the screen, but you’ve set the y-coordinate to zero, which is surely the bottom.” I’m afraid that Flash is weird in that respect: y increases as you go down the screen. For my 400 by 300 pixel stage, the coordinates look like this:

screenshot

You get used to it.

I’m going to handle the movement by having something else tell the Enemy to move downward, just a little bit, every split-second. We need to add this movement functionality to the Enemy class, since MovieClips don’t already have something that can do that, so let’s create a new function:

?View Code ACTIONSCRIPT3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package 
{
	import flash.display.MovieClip;
	public class Enemy extends MovieClip 
	{
		public function Enemy() 
		{
			x = 100;
			y = 0;			
		}
 
		public function moveDownABit():void 
		{
			y = y + 3;
		}
	}
}

Let’s break this down again:

  • function moveDownABit() — everything between the following pair of curly brackets makes up a function called moveDownABit. Again, we have that empty pair of parenthesis after the function name.
  • public — another part of the game is going to actually run this function, so it needs to be public.
  • :void — this function does not return any feedback. Don’t dwell on this; I’ll explain it when we make a function that does return something.
  • y = y + 3; — increase the y-coordinate of the Enemy by 3 pixels (remember, this will move the enemy downwards, not upwards).

Making an Enemy

Save your Enemy.as file and go back to the FLA file. Our next step is to get an actual enemy into the game; up till now we’ve just been dealing with a template of an Enemy, not an actual enemy itself. It’s like we’ve been working on a blueprint, and now we need to use that blueprint to build an actual, physical house.

It’s important to remember that Flash started off as a tool for creating animating movies. Even though it’s developed a lot since then, Flash still considers everything you create with it to be a MovieClip. As we know, MovieClips have a constructor function that runs when they’re created, and therefore so does your game. We’re going to extend this function to make it create an Enemy within the game when the game is started. But how do we access the game’s constructor? If you said, “another AS file,” you’re correct.

Create a new AS file, and save it in the Classes folder with the name AvoiderGame.as. Add these lines to the file, and save it:

?View Code ACTIONSCRIPT3
1
2
3
4
5
6
7
8
9
10
11
package 
{
	import flash.display.MovieClip;
	public class AvoiderGame extends MovieClip 
	{
		public function AvoiderGame() 
		{
 
		}
	}
}

Look familiar? Apart from the names of the class and the constructor, it’s exactly the same as our Enemy AS file started out. Let’s link it to our FLA file.

Move back to the FLA file and make sure you’re not still editing the Enemy. Find the Properties panel — if you can’t see it, make sure Window > Properties > Properties is checked. There’s a box marked Document class; enter AvoiderGame. It’s important to use capital letters in the right places here — since we’ve called the file AvoiderGame.as and the class within the file AvoiderGame, we have to follow suit with the name of the document class. Clicking the little pencil icon should bring up the AvoiderGame class file.

screenshot

Great, so now we can edit the actual game’s constructor to make it create an enemy at startup:

?View Code ACTIONSCRIPT3
1
2
3
4
5
6
7
8
9
10
11
package 
{
	import flash.display.MovieClip;
	public class AvoiderGame extends MovieClip 
	{
		public function AvoiderGame() 
		{
			enemy = new Enemy();
		}
	}
}

Watch your capitalisation here! Enemy with a capital E is the class file that defines features common to all Enemies; enemy with a small e is a specific example — an “instance” — of an Enemy. It’s like, Person is a class, but I am an instance of that class, and you are another instance of that class.

At the minute, this instance, enemy, of Enemy is only available to the constructor function, because it is first referred to within that function. We need it to be available throughout the entire game, so add this line of code (line 6):

?View Code ACTIONSCRIPT3
1
2
3
4
5
6
7
8
9
10
11
12
13
package 
{
	import flash.display.MovieClip;
	public class AvoiderGame extends MovieClip 
	{
		public var enemy:Enemy;
 
		public function AvoiderGame() 
		{
			enemy = new Enemy();
		}
	}
}
  • public — you know what this means.
  • var — “the following is a new variable that I am defining.”
  • enemy:Enemy — “the variable is called enemy, and it is an instance of the Enemy class.”

Since the enemy variable is defined within the AvoiderGame class, it’ll be available throughout the class.

So now we’ve created an enemy, but it’s just sort of floating about in the aether. We need to tie it down to the actual game:

?View Code ACTIONSCRIPT3
8
9
10
11
12
		public function AvoiderGame() 
		{
			enemy = new Enemy();
			addChild( enemy );
		}

Here’s a new function: addChild(). We use this to make objects actually appear on-screen. Any object that is “addChild()-ed” to the document class (remember, the AvoiderGame class is our document class) will appear on-screen — well, as long as its x- and y-coordinates are inside the rectangle that make up the screen!

We say that the enemy is now a child of the AvoiderGame class, and that the AvoiderGame class is the enemy’s parent. An object can only have one parent, but it can have as many children as you like.

At last, we can run the game and expect some results! Save everything, then hit Control > Test Movie. You’ll get something like this:

screenshot

Hooray! Only… we want all of the enemy to start above the window, not just half of it. What Flash has done is position the enemy so that its registration point is positioned at the point (100,0). We could move the registration point to the bottom of the enemy, but I think that’s a sloppy solution. Instead, let’s just change the enemy’s starting y-position; alter the constructor in the Enemy.as file like so:

?View Code ACTIONSCRIPT3
6
7
8
9
10
		public function Enemy() 
		{
			x = 100;
			y = -15;
		}

You’ll need to alter that y-value depending on the height of your Enemy (mine’s 30 pixels tall).

Bringing the Enemy to Life

Although we’ve built in some functionality to let the enemy move downwards, we haven’t written any code that actually tells the enemy to do so. Let’s do that next.

The basic idea, as I outlined above, is to have the game tell the enemy to move a few pixels down every split-second. Frozen Haddock’s tutorial used a couple of neat methods for achieving this, but we don’t need to use either of those, because AS3 has a new solution: the Timer class that does it all for us.

Edit the game’s constructor function to create a new instance, gameTimer, of the Timer class. This is a built-in class, so you don’t need to create a new AS file; just edit AvoiderGame.as like so::

?View Code ACTIONSCRIPT3
8
9
10
11
12
13
14
		public function AvoiderGame() 
		{
			enemy = new Enemy();
			addChild( enemy );
 
			gameTimer = new Timer( 25 );
		}

Note that this time the parenthesis after the class name are not empty. That number 25 says that we want to set the interval of the timer to 25ms (milliseconds; 1000ms = 1 second), i.e., we want it to do something every 25ms.

We want this gameTimer to last throughout the game, of course, so we need to make it available to the entire class (line 7):

?View Code ACTIONSCRIPT3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package 
{
	import flash.display.MovieClip;
	public class AvoiderGame extends MovieClip 
	{
		public var enemy:Enemy;
		public var gameTimer:Timer;
 
		public function AvoiderGame() 
		{
			enemy = new Enemy();
			addChild( enemy );
 
			gameTimer = new Timer( 25 );
		}
	}
}

…and Timer is like MovieClip, in that Flash has to be told about it before we can use it (line 4):

?View Code ACTIONSCRIPT3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package 
{
	import flash.display.MovieClip;
	import flash.utils.Timer;
 
	public class AvoiderGame extends MovieClip 
	{
		public var enemy:Enemy;
		public var gameTimer:Timer;
 
		public function AvoiderGame() 
		{
			enemy = new Enemy();
			addChild( enemy );
 
			gameTimer = new Timer( 25 );
		}
	}
}

(By the way, don’t worry about how I know that it’s flash.utils.Timer and flash.display.MovieClip; I looked it up.)

All right, so we have a Timer that goes off every 25ms. But at the minute it’s not connected to anything; it’s not telling the enemy to move down the screen. So, add the following (line 17) to your game’s constructor:

?View Code ACTIONSCRIPT3
11
12
13
14
15
16
17
18
		public function AvoiderGame() 
		{
			enemy = new Enemy();
			addChild( enemy );
 
			gameTimer = new Timer( 25 );
			gameTimer.addEventListener( TimerEvent.TIMER, moveEnemy );
		}
  • gameTimer.addEventListener — “apply an event listener to the gameTimer with the following parameters.” An event listener is like a robot that’s constantly checking to see if a particular “event” has occurred, and which runs another function if so. In this case, the event is…
  • TimerEvent.TIMER — this event goes off every time a Timer completes an interval; in our case, this event will be triggered every 25ms, because that is the interval of the gameTimer.
  • moveEnemy — this is the function that’s going to be run every time the TimerEvent occurs. We haven’t written this function yet; we’ll get to that in a minute.

TimerEvent is yet another thing that Flash has to be told about, so import it at the top (line 5):

?View Code ACTIONSCRIPT3
1
2
3
4
5
package 
{
	import flash.display.MovieClip;
	import flash.utils.Timer;
	import flash.events.TimerEvent;

Now we need to write that moveEnemy function that’ll actually be run every 25ms (lines 21-24):

?View Code ACTIONSCRIPT3
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
	public class AvoiderGame extends MovieClip 
	{
		public var enemy:Enemy;
		public var gameTimer:Timer;
 
		public function AvoiderGame() 
		{
			enemy = new Enemy();
			addChild( enemy );
 
			gameTimer = new Timer( 25 );
			gameTimer.addEventListener( TimerEvent.TIMER, moveEnemy );
		}
 
		public function moveEnemy( timerEvent:TimerEvent ):void 
		{
 
		}
	}

Again, we’ve got something inside the parenthesis. This allows the event listener to pass information about the event through to the moveEnemy function, in the form of an instance (timerEvent) of the class TimerEvent. We don’t need to know any of that information, however, so we won’t be referring to it again. Also, there’s void again.

All we have to do now is use this new function to tell the enemy to move. Remember the moveDownABit function we put inside Enemy earlier? Time to make use of it:

?View Code ACTIONSCRIPT3
21
22
23
24
		public function moveEnemy( timerEvent:TimerEvent ):void 
		{
			enemy.moveDownABit();
		}

So this tells the enemy instance to run its moveDownABit function. Save everything, and run the game (Control > Test Movie, remember).

Nothing happens.

We have to tell the gameTimer to start! Go ahead and edit your game’s constructor as below (line 19):

?View Code ACTIONSCRIPT3
12
13
14
15
16
17
18
19
20
		public function AvoiderGame() 
		{
			enemy = new Enemy();
			addChild( enemy );
 
			gameTimer = new Timer( 25 );
			gameTimer.addEventListener( TimerEvent.TIMER, moveEnemy );
			gameTimer.start();
		}

Save everything, and run it again. Success! The enemy is moving downscreen, at a healthy rate of 3 pixels per 25ms (or 120 pixels/second).

Now we need to add some amount of interactivity, otherwise this is just a movie and not a game.

Get your Head in the Game

First we have to make our player’s avatar. In your FLA file, create a new symbol, of type Movie Clip, called Avatar. (Check out the section above on creating the enemy if you can’t remember how to do this.) Draw whatever you want to represent the player. Frozen Haddock defied convention again by picking a skull for his protagonist. I want to get in on some of this action.

screenshot

Don’t feel bad if your drawings aren’t anywhere near as good as mine. After all, I do have a GCSE in graphic design.

Alright, so once you’ve made your Avatar, centred the registration point, got out of editing mode, and saved the FLA, what’s next? You will probably not be surprised to hear that we’re going to create a new AS file for the Avatar. Save it as Avatar.as in the Classes folder, and start editing it:

?View Code ACTIONSCRIPT3
1
2
3
4
5
6
7
8
9
10
11
package 
{
	import flash.display.MovieClip;
	public class Avatar extends MovieClip 
	{
		public function Avatar() 
		{
 
		}
	}
}

Same old story. Go ahead and link it to the Avatar in the Library.

What is our avatar going to do? At the minute, it’s just going to follow the mouse around the screen — effectively, it’ll be a mouse pointer. We can actually control the avatar’s position from within the AvoiderGame class, so we don’t need to add any more code to the Avatar class right now.

Switch to editing the AvoiderGame.as file, and let’s add an instance of the Avatar class to the game. I’ll put in all the code at once, this time, since it’s pretty much the same as when we did it for the enemy. (The following is in the AvoiderGame.as file) (New code: lines 10, 18, & 19):

?View Code ACTIONSCRIPT3
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
	public class AvoiderGame extends MovieClip 
	{
		public var enemy:Enemy;
		public var avatar:Avatar;
		public var gameTimer:Timer;
 
		public function AvoiderGame() 
		{
			enemy = new Enemy();
			addChild( enemy );
 
			avatar = new Avatar();
			addChild( avatar );
 
			gameTimer = new Timer( 25 );
			gameTimer.addEventListener( TimerEvent.TIMER, moveEnemy );
			gameTimer.start();
		}
 
		public function moveEnemy( timerEvent:TimerEvent ):void 
		{
			enemy.moveDownABit();
		}
	}

If you run the game now, you’ll see that the avatar instance appears in the top left corner of the screen — i.e., at position (0,0). We want it to start off wherever the mouse cursor is. Flash has two properties we can use for this: mouseX, which gives the x-coordinate of the mouse cursor, and mouseY, whose functionality you can probably guess. As mentioned above, anything that extends a MovieClip will have an x and a y property that we can edit. So (lines 20 & 21):

?View Code ACTIONSCRIPT3
13
14
15
16
17
18
19
20
21
22
23
24
25
26
		public function AvoiderGame() 
		{
			enemy = new Enemy();
			addChild( enemy );
 
			avatar = new Avatar();
			addChild( avatar );
			avatar.x = mouseX;
			avatar.y = mouseY;
 
			gameTimer = new Timer( 25 );
			gameTimer.addEventListener( TimerEvent.TIMER, moveEnemy );
			gameTimer.start();
		}

If you run this, the avatar will indeed appear at the mouse cursor (this is easier to see if you use the keyboard shortcut for Test Movie which is Ctrl-Enter on Windows and Command-Enter on Macs). Since we use the gameTimer to alter the enemy’s position every split-second, let’s also use it for the avatar’s position (lines 31 & 32):

?View Code ACTIONSCRIPT3
28
29
30
31
32
33
		public function moveEnemy( timerEvent:TimerEvent ):void 
		{
			enemy.moveDownABit();
			avatar.x = mouseX;
			avatar.y = mouseY;
		}

Oh, wait, moveEnemy isn’t really a suitable name for the function now. How about moveEnemyAndAvatar?

?View Code ACTIONSCRIPT3
28
29
30
31
32
33
		public function moveEnemyAndAvatar( timerEvent:TimerEvent ):void 
		{
			enemy.moveDownABit();
			avatar.x = mouseX;
			avatar.y = mouseY;
		}

We’ll have to update the gameTimer’s event listener to point to this function with its new name, or it’ll get confused:

?View Code ACTIONSCRIPT3
24
			gameTimer.addEventListener( TimerEvent.TIMER, moveEnemyAndAvatar );

Save and run the game, and bask in the glory of your new, skull-shaped mouse cursor!

screenshot

Putting the “Avoid” in “Avoider Game”

You might have noticed that if you do happen to run your avatar into the enemy… absolutely nothing happens. This isn’t very good for an avoider game, so let’s correct that.

How will we know if the avatar has hit the enemy? MovieClips have a built-in function called hitTestObject which detects whether the MovieClip is touching another specified MovieClip. Naturally our Avatar and Enemy classes have this as well. Since the objects only move when the gameTimer goes off, we should check for a collision in the gameTimer’s event listener’s connected function (lines 34-37):

?View Code ACTIONSCRIPT3
28
29
30
31
32
33
34
35
36
37
38
		public function moveEnemyAndAvatar( timerEvent:TimerEvent ):void 
		{
			enemy.moveDownABit();
			avatar.x = mouseX;
			avatar.y = mouseY;
 
			if ( avatar.hitTestObject( enemy ) ) 
			{
 
			}
		}
  • avatar.hitTestObject( enemy ) — this will return a value of true if the avatar is touching the enemy
  • if — “if the statement between the next pair of parenthesis is true, then run the code between the next pair of curly brackets

At the minute there’s nothing between the curly brackets, so nothing will happen upon a collision. Before we add anything there, we should really change the name of the moveEnemyAndAvatar function, since once again it is no longer accurate. I can see that we’ll be adding more and more to this function in future parts of this tutorial, so let’s not bother with a cumbersome name like moveEnemyAndAvatarAndAlsoCheckToSeeIfTheyHaveCollided. Instead, I’m going to define a new word:

  • Tick — every time the gameTimer goes off, that’ll be called a Tick from now on. Everything that needs to be updated or checked will occur once per Tick.

So now we can rename the function to onTick:

?View Code ACTIONSCRIPT3
28
29
30
31
32
33
34
35
36
37
38
		public function onTick( timerEvent:TimerEvent ):void 
		{
			enemy.moveDownABit();
			avatar.x = mouseX;
			avatar.y = mouseY;
 
			if ( avatar.hitTestObject( enemy ) ) 
			{
 
			}
		}

Don’t forget to change the gameTimer’s event listener to point to the new name. We won’t need to alter it again after this.

Finally, let’s make the game actually do something when the enemy hits the avatar. Since I haven’t covered lives, we haven’t made a game over screen, and there’s no scoring system yet, I’ll take this as an opportunity to show you something.

You know how we had to start the gameTimer before anything happened? Well, add this to your onTick event (line 34):

?View Code ACTIONSCRIPT3
28
29
30
31
32
33
34
35
36
		public function onTick(event:TimerEvent):void {
			enemy.moveDownABit();
			avatar.x=mouseX;
			avatar.y=mouseY;
 
			if (avatar.hitTestObject(enemy)) {
				gameTimer.stop();
			}
		}

Now save and run the game, and see what happens when you run into the enemy. Don’t worry, the game hasn’t crashed; we’re just no longer running any Tick code. Two things we can notice from this:

  1. The collision detection is terrible
  2. A pause feature is going to be very easy to implement later

Wrapping Up

So there’s your very basic Avoider Game. If you want to modify it and give all the code to someone else, just zip up the main folder (mine was called AvoiderGame-MJW, remember) and send it to them. You can download mine from this link. Alternatively, if you just want to give them the game itself, without them being able to edit it, switch to your FLA, select File > Export > Export Movie, give a name to your SWF file, and send that instead.

I realise that what we’ve got so far is very crude, both in terms of code and gameplay. Now that we’ve got the basic framework down, future parts of the tutorial will be able to add more in less time. In the next part, we’ll add multiple enemies, and after that we’ll be adding a clock, and a game over screen, and lives, and a scoring system, and, well, everything that Frozen Haddock’s series has.

Thanks for reading!

Edit: The next part is available!

{ 361 comments… read them below or add one }

Dean January 21, 2012 at 5:31 am

Hello MIchael,i got a problem on how to link the class to Enemy graphic,when i tick the pencil icon it says "A definition for this class could not be found in the classpath,so one will be generated in the SWF file upon export'.I'm pretty sure i follow all the instructions properly,help me!!!

Michael James Williams January 30, 2012 at 3:03 pm

Hey Dean,

That basically means it couldn’t find the Enemy.as file in the /classes/ directory. Is it in there?

Dean January 31, 2012 at 5:28 pm

yeah,i'm  sure its in there,i dont know if its my FlashCS3 prob or something else.

_<

Pika February 1, 2012 at 4:02 pm

Hello :) I need some help with this – I have been following the instructions and everything has worked up to the “Bringing the Enemy to Life” part… for some reason my enemy is not moving down the screen? I’m pretty sure I put in the correct script, so is could there be another reason why it’s not working?
Thanks!!

Ben February 13, 2012 at 4:38 pm

I’m operating off of CS4…

I keep getting an error “1061: Call to a possibly undefined method moveDownABit through a reference with static type Enemy.”, so I haven’t move on to the Avatar bit yet… How do I fix the 1061 error?

My AvoiderGame.as code is:

package 
{
    import flash.display.MovieClip;
    import flash.utils.Timer;
    import flash.events.TimerEvent;

public class AvoiderGame extends MovieClip 
{
    public var enemy:Enemy;
    public var gameTimer:Timer;

public function AvoiderGame() 
{
    enemy = new Enemy();
    addChild(enemy);

    gameTimer = new Timer( 25 );
    gameTimer.addEventListener( TimerEvent.TIMER, moveEnemy );
    gameTimer.start();
}

public function moveEnemy( timerEvent:TimerEvent ):void
{
    enemy.moveDownABit();

}

}

}

I don’t know if it helps, but my Enemy.as code is

package 
{
    import flash.display.MovieClip;
    public class Enemy extends MovieClip 
    {
        public function Enemy() 
        {
            x = 100;
            y = -30;
        }

    public function MoveDownABit():void
    {
        y = y + 3;
    }
}

}

Thanks!
–Ben

SkeleDog February 22, 2012 at 1:21 am

Hey there Michael,
I have some questions (I hate to necro-post buuut…)that have been burning in my mind reguarding the OOP aspect of these tutorials. I guess It could be because I haven’t gone through the extent of this whole tutorial but I’m totally clueless as to how I would plan a program in this format. It is rather confusing to me whether I should throw components in their own class or should they go into the Document Class (main loop)… I could just be over analyzing but I don’t quite understand how to discern which functions should be isolated into seperate classes from the one running directly through the FLA.
Thanks to Michael for these great beginner tutorials and to anyone that can illuminate on this matter for me!
~Paul

SkeleDog February 22, 2012 at 1:32 am

I just posted this before but I got the notice that it was a duplicate comment?

Hey there Michael,
I have some questions (I hate to necro-post buuut…)that have been burning in my mind reguarding the OOP aspect of these tutorials. I guess It could be because I haven’t gone through the extent of this whole tutorial but I’m totally clueless as to how I would plan a program in this format. It is rather confusing to me whether I should throw components in their own class or should they go into the Document Class (main loop)… I could just be over analyzing but I don’t quite understand how to discern which functions should be isolated into seperate classes from the one running directly through the FLA.
Thanks to Michael for these great beginner tutorials and to anyone that can illuminate on this matter for me!
~Paul

Martin March 1, 2012 at 12:31 pm

Great tutorial!
@Dean Check if you included the path to the classes folder (in publish settings)

GeorgeMan March 6, 2012 at 9:01 pm

Hello Michael,
I’ve been going through you tutorials, and I’ve come to a point where I would like to add some own features. I’ve been trying to make the background move, but I just don’t get it. I’ve added a new class, as we did for the enemy, made a function to move the movieclip, but when I add the function to the onTick function to launch it and then run my game, it throws out an error on every Tick(!)
Could you tell me where or how I have to put my function?

Thanks in advance!

mk March 11, 2012 at 4:03 pm

@dean
possibly you have created a file like “enemy.as.fla” … when you create the file be sure you select “script” . When you save the file the type should not be *.fla.

Jonathan March 18, 2012 at 10:23 am

This coding seems very familiar to me the object orientated part. I just don’t understand why your code looks so different to say Kongregates shootorial. You use a timer to animate the code where i would have thought you could have just used the onEnterFrame() function. Could it be done either way? What would the pro’s and con’s be if it was done in the respective manners?

Unplugged March 21, 2012 at 2:08 pm

Yeah im having same problem too..”A definition for this class could not be found in the classpath,so one will be generated in the SWF file upon export’ but the enemy is there in classes folder..anyone can help?…using cs3

Jables March 24, 2012 at 5:15 am

Hey Michael, I am new to programming. I went through your Tutorial using CS5.5 but when I get to the point to test the code the Enemy doesn’t appear. I have tried programming in C++ and others but I can never get my media showing in my tests. Can you give me some advice please?

sujai March 28, 2012 at 10:41 am

Hi Michael James Williams , superb stuff ,expecting more…

Sketchist March 31, 2012 at 5:14 pm

WOW. Just this simple part of the tutorial has taught me a lot! You are one of the best people to create tutorials you actually explain it!

Ben April 3, 2012 at 4:46 pm

This is great, you’re the best writer for tutorials I have come across from forums to books. Thanks again, Ben

Usman Salim April 4, 2012 at 12:46 pm

i created this game on my home pc using cs3 and it works perfect however i took it my univeristy where they have cs5.5 and the swf file starts up the same way however when i press the start button the game doesnt play.

Please help!!

thanks is advance

Jaynus April 13, 2012 at 2:28 am

Hey not sure if you still read these, tried to follow through but right when I make the enemy move I get a #1006 error saying moveDownABit is not a function
(avoid2 is what I saved the name under)

TypeError: Error #1006: moveDownABit is not a function.
at avoid2/moveEnemy()
at flash.utils::Timer/_timerDispatch()
at flash.utils::Timer/tick()

package 
{
    import flash.display.MovieClip;
    import flash.utils.Timer;
    import flash.events.TimerEvent;

public class avoid2 extends MovieClip
{
    public var enemy:Enemy;
    public var gameTimer:Timer;
    public function avoid2()
    {
        enemy = new Enemy();
        addChild( enemy );

    gameTimer = new Timer(25);
    gameTimer.addEventListener( TimerEvent.TIMER, moveEnemy );
    gameTimer.start();

}
public function moveEnemy( timerEvent:TimerEvent ):void
{
    enemy.moveDownABit();
}

}

}

Jaynus April 13, 2012 at 12:46 pm

LOL I figured it out, I enemy.as had to be saved as Enemy.as :|

Chloe April 17, 2012 at 4:04 pm

hey michael, your tutorial is great, and i hope to look at more of them if im not put off by this error im after getting, :/. it just says ‘packages cannot be nested’ and iv looked online for an answer but im just more confused… any suggestions? thank you.

Jasper Verelst April 18, 2012 at 8:17 pm

Hi Dean, maybe this is no more use for you any more now but what you should do is check where you defined the classpath ./Classes/ and make sure it is there. Possibly you entered this but it didn’t got saved, which is what happened to me… ^^

Charlie April 23, 2012 at 11:29 pm

Michael, this is my first time attempting to write any kind of code, and this tutorial is fabulous! It’s easy to follow and understand, and really enjoyable to go through. I’m genuinely looking forward to completing all 12 parts.
My aim is really to have the necessary tools to put any game ideas I have into action, so what would your recommendation be for a next step to take after finishing this tutorial?
Many thanks.

Joel May 3, 2012 at 7:26 pm

Hi, great tutorial so far but I’ve had a stumbling block!

when I click the pencil (after right-click > properties on the 1st library image) it brings up a new AS file. Is this right, should I now have A flash file and 2 AS files (one being the Enemy.AS that I placed in the classes folder).

If so, what do I save this new AS file as and where?
If not, which AS file do I use?

Brannie May 11, 2012 at 3:13 pm

Hey Michael,

This is an awesome tutorial and pretty much exactly what I need :)
Thank you very much for making the tutorial available and easy to understand, even for a newbie like me :)

Odin May 20, 2012 at 1:51 am

Thanks MJW for this wonderful tutorial. It is all coming together becasue I started on AS2 and now I am just trying AS3 and it feels like I all ready know whats going to happen, but just don’t know what codes to put in. :) I’ll tell you once my Avoider Game is done. Plzzz message me when your making new tutorial so I can learn more :D

param June 3, 2012 at 1:00 pm

Can you please send me send me the files.i am not able to make it

Steve June 13, 2012 at 11:04 pm

I’m having the same exact issue as Dean. I keep getting the SWF file path error and followed this tutorial to a T up to that point. Not sure what the deal is.

Nate June 19, 2012 at 7:23 pm

To Dean,
I wanna guess that you saved your file exactly as “Enemy” in your folder. What you should do is in the save as box type “Enemy.as” when saving the AS file. If you don’t type “.as” at the end then it wont work.

James W June 24, 2012 at 9:17 am

hey,

brand new on the flash scene and loving every second im learning something new.
I got stuck on what seems to be a rather silly mistake.Ive done the coding exactly as you lay it out step by step and upon testing the file for the first time (there where we change the coordinates so the enemy starts of screen and not half on half off i get stuck with these error reports

C:\Users\Dom\Desktop\game ideas\test game\avoider jwr\classes\Enemy.as, Line 4 1017: The definition of base class MovieClip was not found.
C:\Users\Dom\Desktop\game ideas\test game\avoider jwr\classes\Enemy.as, Line 1 5000: The class ‘Enemy’ must subclass ‘flash.display.MovieClip’ since it is linked to a library symbol of that type.
C:\Users\Dom\Desktop\game ideas\test game\avoider jwr\classes\AvoiderGame.as, Line 1 5000: The class ‘AvoiderGame’ must subclass ‘flash.display.MovieClip’ since it is linked to a library symbol of that type.

im stumped,would you please help me

Colin June 27, 2012 at 6:00 am

MJW,

This is a great tutorial and everything was going grand until after i addChild-ed the enemy, and Ctrl-Entered, and tested the movie. My enemy isnt showing up at all. after checking syntax and file names, i noticed a problem in the .fla that says:
” Line 1 5001: The name of package ‘Enemy’ (and AvoiderGame in the second error) does not reflect the location of this file. Please change the package definition’s name inside this file, or move the file. C:\Users\Colin Z\Documents\Colin’s Work\Independent Coding\Flash-Actionscript\Programs\AvoiderGame\Classes\Enemy.as”

Nic July 9, 2012 at 4:26 am

I just wanted to say, this tutorial is absolutely fantastic, and you’re amazing for posting it. I’ve programmed stuff before, but I’ve never used Actionscript 3, and was a bit wary of going anywhere near it, as I was used to a few things out of AS2, such as being able to put code directly onto buttons and such.

This has helped me out immensely, it’s well-written, explains things really well, and in a way that’s incredibly easy to understand without feeling patronising, and doesn’t really ‘gloss over’ anything. What I’m trying to say is thanks, and keep being awesome.

Nano July 17, 2012 at 11:50 pm

Hi!

I was following the tutorial, and in the part where we test the movie to see if the enemy is working properly i got two error messages:
One in the AvoiderGame.as file, that goes like this:
1046: Type was not found or was not a compile-time constant: .
Source: public var enemy:Enemy();
Another one in the Enemy.as file:
5000: The class ‘Enemy’ must subclass ‘flash.display.MovieClip’ since it is linked to a library symbol of that type.

Michael James Williams August 1, 2012 at 8:56 pm

Thanks Nic!

Michael James Williams August 1, 2012 at 8:58 pm

Nano: Check out How to Fix Any Bug.

Reggie D August 20, 2012 at 1:48 am

Michael,

Thanks so much for this amazing tutorial… it was my parachut into Flash and AS3!

It also inspired me to write this blog post:
http://ifexpertelselearn.wordpress.com/2012/08/20/twisting-tutorials-as-a-flash-actionscript-3-beginner/

Which others might find an interesting read…

Reggie D

edualc August 26, 2012 at 12:25 pm

Howdy Michael,
I have the same question as SkeleDog.
” I’m totally clueless as to how I would plan a program in this format. It is rather confusing to me whether I should throw components in their own class or should they go into the Document Class (main loop)… I could just be over analyzing but I don’t quite understand how to discern which functions should be isolated into separate classes from the one running directly through the FLA.”

I’ve developed a few games using the timeline and all in flash but it’s getting messy and complicated so I am here to try to get the basics right before carrying on.
do you have a link or an answer to his question ?

thanks in advance
Edualc

eduflash August 26, 2012 at 6:05 pm

It seems to not work in CS5, needs updating possibly.

Jackson August 28, 2012 at 11:23 pm

I did everything in the class-binding thing, and I checked that I had saved the ./Classes/ path, but it gives me an error: “1180: Call to a possibly undefined method enemy”

It says it was on the “AvoiderGame” class.

The enemy is also not moving along the screen at all, and is not at the top of the level either.

Toni August 30, 2012 at 12:23 am

hey, thank you for that awsome tutorial. When I first visit your blog I knew very little about as3 but with your help I made my first game, and learn lot more about programming, keep rockin’ !

qhaiz September 4, 2012 at 10:17 am

i am using cs5 …… can it be possiblee…..

hasan September 13, 2012 at 12:50 pm

Very good tutorial, 2 thumbs up… :)

Lucas Horta November 22, 2012 at 5:16 am

Wow, that’s so brilliant, you have a way to explain things that makes me so comfortable to understand it all, thank you man!

Mark December 2, 2012 at 10:00 pm

I have followed this tutorial very carefully, and when i run the code i get error
TypeError: Error #1034: Type Coercion failed: cannot convert flash.events::TimerEvent@277531f1 to flash.utils.Timer.
at flash.utils::Timer/_timerDispatch()
at flash.utils::Timer/tick()
Ive restarted and redone the tutorial up to the same point and cant get this to run, the sprite appears but wont move down

amit gupta December 13, 2012 at 8:25 am

Thanks Michael for this nice tutorial. It has really made AS3 coding so easy to learn and use.

cabezotta December 13, 2012 at 8:18 pm

thanks!! it’s very usefull!!

Charles Davis December 16, 2012 at 6:26 pm

I’m having the same problem using CS5.5 the enemy doesn’t display. I’d like to thank everyone for trying to have a community that shares. But I have yet to find a tutorial for AS3 using CS5.5 that works. I’m not new to programming I’ve been at it for 30 years. My suggestion is ALWAYS include a download of the code, having a working demo and at the very beginning of the tutorial, Document your setup. ie. Adobe Web Premium CS5.5, Flash Professional or Builder. Thnaks Much and I’ll keep looking for a working tutorial

Hot In One December 28, 2012 at 2:50 pm

Where is the tutorial about how to use Flashdevelop to create flash game? I have spent days to find the neat one, but no result. is there anybody who can suggest me a site?

ali ahmad December 29, 2012 at 6:47 am

I just wonder does this work on cs5 because I when right through it and does not work. What did i do wrong. Thanks please help..

abhinav January 11, 2013 at 2:01 pm

I cannot say enough of thanks to you man :-) Great article and obviously following u on twitter

Jakub Wałkowski January 12, 2013 at 11:56 am

Hi Mike!
Polish site that u link is down now and no one have a safe copy.
Can I translate it again and put on my site? (I going to do special one for this and some others Flash GameDev tutorials)

Regards,
Jacob

Leave a Comment

Writing code? Write <pre> at the start and </pre> at the end to keep it looking neat.

Anti-Spam Protection by WP-SpamFree

{ 24 trackbacks }

Previous post:

Next post: