Video icon 64
Build your coding skills with practical video courses from Tuts+. Start your free trial today.

Create a Whack-a-Mole Game in Flash With AS3

Student iconAre you a student? Get a yearly Tuts+ subscription for $45 →

In this tutorial, you'll learn how to create your own version of the classic Whack-a-Mole game - only, our unfortunate creatures of choice will be worms. You'll be able to modify the speed of the game and the hit boxes of the worms.

Step 1: Brief Overview

We'll use common ActionScript 3 classes, specially Mouse Events to create an entertaining Whack A Mole like game in Flash

Step 2: Flash Document Settings

Open Flash and create a 480 pixels wide, 320 pixels tall document. Set the Frame rate to 24fps.

(Note: there's a mistake in the image above; the width and height are the wrong way round! Thanks to Roel Traa for pointing this out.)

Step 3: Interface

A simple and friendly interface will be used, featuring several shapes, buttons and MovieClips, continue to the next steps to build this GUI.

Step 4: Background

Select the Rectangle Tool (R) to create a 320x480px #CC9866, #BA7743 rectangle and center it in the stage.

Step 5: Title

Use the Text Tool (T) to add a title using your favorite font. You can also use some of the graphics of the game to make it nicer. The worm graphic used in this tutorial was downloaded from here under a Creative Commons License.

Step 6: Buttons

Use again the Text Tool to create three buttons as shown in the image above. Convert them to buttons and give them descriptive instance names to easily use them later in the code. Convert the graphics in stage to a single MovieClip and name it TitleView, remember to check the Export for ActionScript box.

Step 7: Options

Clear the last view except the background and create a series of Dynamic TextFields as shown in the image, give them descriptive instance names and convert them to buttons. Use the Rectangle Tool (R) to create an arrow button that will be used to go back to the Title Screen.

Step 8: Credits

The Credits screen will appear in front of the Title Screen, use the graphics and fonts used before to create it. Name it CreditsView and remember to check the Export for ActionScript box.

Step 9: Game Screen

Simple cartoonish graphics are used in the Game Screen, there's not really a procedure to create this graphics just use your imagination and the Flash drawing tools to create something like the image above. Every hole in the game screen is a MovieClip that contains an animation of the Worm coming out, it's basically a simple frame by frame animation, be sure to check the source to for better comprehension.

Step 10: Alert

An alert will be shown when all the Worms have shown, it will display the final score you reached. Use the Rectangle Tool to create it and add a descriptive name to the bottom TextField, set its instance name to AlertView and mark the Export for ActionScript box.

Step 11: TweenNano

We'll use a different tween engine from the default included in flash, this will increase performace as well as being easier to use.

You can download TweenNano from its official website.

Step 12: Soungle

We'll use Sound Effects to enhance the feeling of the game, you can find the sound used in this example in using the keyword hit.

Step 13: Set Document Class

We'll make our application interactive by using an external class, add its name to the Class field in the Publish section of the Properties panel to associate the FLA with the Main document class.

Step 14: Create a New ActionScript Class

Create a new (Cmd + N) ActionScript 3.0 Class and save it as in your class folder.

Step 15: Class Structure

Create your basic class structure to begin writing your code.

	import flash.display.Sprite; 
	public class Main extends Sprite 
		public function Main():void 
			// constructor code 

Step 16: Required Classes

These are the classes we'll need to import for our class to work, the import directive makes externally defined classes and packages available to your code.

import flash.display.Sprite; 
import flash.text.TextField; 
import flash.utils.Timer; 
import com.greensock.TweenNano; 
import com.greensock.easing.Expo;

Step 17: Variables

These are the variables we'll use, read the comments in the code to know more about them, some of their names are self explaining so there will be no comment there.

private var titleView:TitleView = new TitleView(); 
private var options:OptionsView; 
private var credits:CreditsView; 
private var lastSelected:TextField; //the last selected speed in the options screen 
private var lastSelected2:TextField; //the last selected hit area in the options screen 
private var hitSize:Number = 1; //hit size mask is at full scale at start 
private var timer:Timer = new Timer(1400); //default time for the worms to appear 
private var holes:Vector.<MovieClip> = new Vector.<MovieClip>(); //stores the 8 holes in stage 
private var currentWorms:int = 0; //worms already shown 
private var wormsHit:int = 0; 
private var totalWorms:String = '10';//total of worms to display

Step 18: Constructor

The constructor is a function that runs when an object is created from a class, this code is the first to execute when you make an instance of an object or runs using the Document Class.

It calls the necesary functions to start the game. Check those functions in the next steps.

public final function Main():void 

Step 19: Start Button Listeners

We'll start by adding the mouse listeners to the buttons in the title view, this will take us to the game, options or credits screen.

private final function startButtonListeners(action:String = 'add'):void 
	if(action == 'add') 
		titleView.creditsB.addEventListener(MouseEvent.MOUSE_UP, showCredits); 
		titleView.optionsB.addEventListener(MouseEvent.MOUSE_UP, addOptions); 
		titleView.playB.addEventListener(MouseEvent.MOUSE_UP, showGameView); 
		titleView.creditsB.removeEventListener(MouseEvent.MOUSE_UP, showCredits); 
		titleView.optionsB.removeEventListener(MouseEvent.MOUSE_UP, addOptions); 
		titleView.playB.removeEventListener(MouseEvent.MOUSE_UP, showGameView); 

Step 20: Add Options

The Options Screen is tweened when the user clicks the options button, a mouse listener is added to the arrow button to remove it when done.

private final function addOptions(e:MouseEvent):void 
	options = new OptionsView(); 
	TweenNano.from(options, 0.3, {x:stage.stageWidth, onComplete:function():void{options.backBtn.addEventListener(MouseEvent.MOUSE_UP, hideOptions);}}); 

Step 21: Options Listeners

This listeners are added when the Options Screen in shown, they handle the buttons on stage. More of its behavior in the next steps.

private final function optionsListeners(action:String = 'add'):void 
	if(action == 'add') 
		options.slowBtn.addEventListener(MouseEvent.MOUSE_UP, changeSpeed); 
		options.mediumBtn.addEventListener(MouseEvent.MOUSE_UP, changeSpeed); 
		options.fastBtn.addEventListener(MouseEvent.MOUSE_UP, changeSpeed); 
		options.smallBtn.addEventListener(MouseEvent.MOUSE_UP, selectHitArea); 
		options.mediumBtn1.addEventListener(MouseEvent.MOUSE_UP, selectHitArea); 
		options.bigBtn.addEventListener(MouseEvent.MOUSE_UP, selectHitArea);

Step 22: Set Default Option

The default options are set by this lines, they set the currently selected buttons which are slow and big.

lastSelected = options.slowBtn.slowTF; 
lastSelected2 = options.bigBtn.bigTF;

Step 23: Remove Option Listeners

A parameter will determine if the listeners are added or removed, the next lines are executed if that parameter doesn't indicate to add the listeners.

		options.slowBtn.removeEventListener(MouseEvent.MOUSE_UP, changeSpeed); 
		options.mediumBtn.removeEventListener(MouseEvent.MOUSE_UP, changeSpeed); 
		options.fastBtn.removeEventListener(MouseEvent.MOUSE_UP, changeSpeed); 
		options.smallBtn.removeEventListener(MouseEvent.MOUSE_UP, selectHitArea); 
		options.mediumBtn1.removeEventListener(MouseEvent.MOUSE_UP, selectHitArea); 
		options.bigBtn.removeEventListener(MouseEvent.MOUSE_UP, selectHitArea); 

Step 24: Hide Options

The arrow button will remove the Options screen when clicked.

private final function hideOptions(e:MouseEvent):void 
{, 0.3, {x:stage.stageWidth, onComplete:function():void{options.removeEventListener(MouseEvent.MOUSE_UP, hideOptions); removeChild(options); options = null;}}); 

Step 25: Change TextField's Color

This function runs when the speed buttons are pressed, its first part changes the text color of the buttons, it changes the current option to white and the new selected value to yellow.

private final function changeSpeed(e:MouseEvent):void 
	/* Change Target and last selected Color */ 
	lastSelected.textColor = 0xFFFFFF; = 0xFF9966;

Step 26: Detect Clicked Button

This is the second part of the speed function, it detects the button clicked checking its name and increases/decreases the Timer accordingly.

if( == 'slowTF') 
		timer = new Timer(1400); 
		lastSelected = as TextField; 
	else if( == 'mediumTF') 
		timer = new Timer(1100); 
		lastSelected = as TextField; 
	else if( == 'fastTF') 
		timer = new Timer(800); 
		lastSelected = as TextField; 

Step 27: Select Hit Area

The next function runs when a button on the hit area selection is clicked. It behaves in the same way as the last function.

private final function selectHitArea(e:MouseEvent):void 
	/* Change Target and last selected Color */ 
	lastSelected2.textColor = 0xFFFFFF; = 0xFF9966; 
	/* Detect clicked button and change hit area accordingly */ 
	if( == 'smallTF') 
		hitSize = 0; 
		lastSelected2 = as TextField; 
	else if( == 'mediumTF') 
		hitSize = 0.5; 
		lastSelected2 = as TextField; 
	else if( == 'bigTF') 
		hitSize = 1; 
		lastSelected2 = as TextField; 

Step 28: Show Credits

The Credits screen is shown when the user clicks the credits button, a mouse listener is added to the full MovieClip to remove it.

private final function showCredits(e:MouseEvent):void 
	titleView.optionsB.visible = false; 
	titleView.creditsB.visible = false; 
	titleView.playB.visible = false; 
	credits = new CreditsView(); 
	TweenNano.from(credits, 0.3, {x:-credits.width, onComplete:function():void{credits.addEventListener(MouseEvent.MOUSE_UP, hideCredits);}}); 

Step 29: Hide Credits

When the Credits screen is clicked it will be tweened back and removed from the stage.

private final function hideCredits(e:MouseEvent):void 
{, 0.3, {x:-credits.width, onComplete:function():void{titleView.creditsB.visible = true; titleView.playB.visible = true; titleView.optionsB.visible = true; credits.removeEventListener(MouseEvent.MOUSE_UP, hideCredits); removeChild(credits); credits = null;}}); 

Let's stop here to make a quick test and make sure that our game code is working:

Keep in mind that some lines have been commented as some functions haven't been created yet.

Remember that the Milestones are included in the source files, so if for some reason your file doesn't mimic this one take a look at the source to see what can be causing that.

Step 30: Show Game View

The following lines remove the Title screen and leaves the Game Screen visible. It also calls a function to prepare the game to be played.

private final function showGameView(e:MouseEvent):void 
{, 0.3, {y:-titleView.height, onComplete:function():void{startButtonListeners('rmv');removeChild(titleView); titleView = null;}}); 

Step 31: Worms Mouse Listeners

We use a for statement here to add a Mouse Listener to every hole MovieClip in the stage. This will make the Worms clickable.

private final function prepareWorms():void 
	for(var i:int = 0; i < 8; i++) 
		/* Add Mouse Listeners */ 
		holes[i].addEventListener(MouseEvent.MOUSE_DOWN, wormHit);

Step 32: Stop Holes MovieClip

As the Hole MovieClip has more than one frame, it need to be stopped to prevent all worms to show at the same time.

		/* Stop Worms At Frame 1*/ 

Step 33: Start Timer

This timer will start the countdown and make to Worms appear randomly in the stage.

private final function startTimer():void 
	timer.addEventListener(TimerEvent.TIMER, showWorm); 

Step 35: Check if Finished

This code checks if the Worms shown have not yet passed the limit and calls an Alert if true.

private final function showWorm(e:TimerEvent):void 
	if(currentWorms == int(totalWorms)) 
		var randomHole:int = Math.floor(Math.random() * 8); // Used to calculate which worm will appear

Step 36: Change Hit Area Size

The selected hit area in the Options screen will be changed here on every worm using the scale properties of AS3.

holes[randomHole].addFrameScript(1, function(){holes[randomHole].worm.hArea.scaleX = hitSize; holes[randomHole].worm.hArea.scaleY = hitSize;});

Step 37: Stop Animation When Finished

A few milliseconds will pass where the Worm will be visible, when the MovieClip reached its last frame it will stop and return to the first frame.

holes[randomHole].addFrameScript(holes[randomHole].totalFrames - 1, function(){holes[randomHole].gotoAndStop(1);}); 

Step 38: Hit Worm

This function handles when a Worm is clicked, it will basically play a sound, raise the score and hide the worm again.

private final function wormHit(e:MouseEvent):void 
	if( == 'hArea' || == 'worm') 
		var hit:Hit = new Hit();; 
		scoreTF.text = wormsHit + '/' + totalWorms; 

Step 39: Check Worms Hit

You can add a custom bonus if all the Worms where hit by changing the next lines of code.

if(totalWorms == String(wormsHit)) 

Step 40: Alert

This function will stop the game and reveal the final score, it also adds a mouse listener to reset the game when clicked.

private final function alert():void 
	var alert:AlertView = new AlertView(); 
	alert.x = stage.stageWidth * 0.5; 
	alert.y = stage.stageHeight * 0.5; 
	alert.scoreTF.text = scoreTF.text; 
	alert.addEventListener(MouseEvent.MOUSE_UP, restart); 
	TweenNano.from(alert, 0.6, {scaleX: 0.2, scaleY: 0.2, ease:Expo.easeOut}); 

Step 41: Restart

The next function will reload the swf, restarting any variable, method and returning to the Title Screen.

private final function restart(e:MouseEvent):void 
	navigateToURL(new URLRequest(stage.loaderInfo.url), '_level0'); 


As you can see many of the game variables/parameters can be modified and adapted to your needs. Try creating your own version of the game!

I hope you liked this tutorial, thank you for reading!