Creating Custom Events In Flash AS3 (ActionScript 3)

I’ve only been working with Flash AS3 for a very short time, but I’m already very happy with it. Even though it is not as accessible as AS2, the power of the new language features are unmistakable. One very powerful feature of AS3 is the built-in event handling. Event handing has existed in Flash as far back as Flash 5, but with AS3 Adobe has forced the issue to the point where using events is really no longer a choice. If you want to create any sort of efficient AS3 application, you will have to learn event handling.

Basic event handling is fairly straight-forward. We’ll start-out by creating a simple game that uses events. This “game” will randomly place circles on the screen that need to be clicked-on. We will start by creating a Game class. The first EventListener required for this Game class to work is an an Event that is fired for onEnterFrame. The code addEventListener(Event.ENTER_FRAME, run) makes the Ball class listen for ENTER_FRAME events and when one is fired, it calls the run() function.

The run() function is used to create new balls on the screen. There is a 10% chance a new ball will be created every frame. After a ball is created, we want to have our game class listen for a CLICKED event from the ball. This event will fire when the mouse is clicked on ball. We will use this event to remove the ball from our Balls array, and score points for the player. The line of code tempBall.addEventListener(Ball.CLICKED, ballClicked); makes sure that our Game class will listen for a CLICKED event. The code below illustrates the complete Game class.

[cc lang=”javascript” width=”550″]/**
* …
* @author Default
* @version 0.1
*/

package {
import flash.display.MovieClip;
import flash.text.TextField;
import flash.events.Event;
import flash.events.MouseEvent;
public class Game extends MovieClip{
private var balls:Array;
private var score:int;
public function Game() {
balls = new Array();
addEventListener(Event.ENTER_FRAME, run);
score = 0;

}

public function run(e:Event):void {
var tempVar:Number = Math.floor(Math.random() * 100);
if (tempVar > 90) {
trace(“create ball”);
var rx:int = Math.floor(Math.random() * 550);
var ry:int = 0;
var tempBall:Ball = new Ball(rx,ry);
tempBall.addEventListener(Ball.CLICKED, ballClicked);
balls.push(tempBall);
addChild(tempBall);
}

for (var i:int = 0; i = 0; i ) {
if (balls[i] == e.target) {
removeChild(balls[i]);
balls.splice(i,1);
score+=e.score;
ScoreText.text = score.toString(); ;
}

}

}

}
}
[/cc]

To shed more light on what the ballClicked() function is doing in the Game class, I must first show you the code for the Ball class:

[cc lang=”javascript” width=”550″]package {
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
public class Ball extends MovieClip{
static public var CLICKED:String = “clicked”;
public var down:Boolean;
public var speed:int =3;
public function Ball(tx:Number, ty:Number) {
x = tx;
y = ty;
addEventListener(MouseEvent.CLICK, mouseClicked);
down=true;

}

public function mouseClicked(e:MouseEvent):void {
dispatchEvent(new ScoreEvent(speed,CLICKED));
}

public function run():void {
if (down){
y += speed;
if (y > 400) {
speed++;
down=false;
}

} else {
y -= speed;
if (y < 0) {
speed++;
down=true;
}
}

}
}

}
[/cc]

This class starts out a lot like the Game class. In the constructor we add this line of code to listen for a mouse CLICK event: addEventListener(MouseEvent.CLICK, mouseClicked); To facilitate this we add a variable named CLICKED as String -“clicked”. This will function our our event identifier. The code looks like this: static public var CLICKED:String = “clicked”; We also need to add a function named mouseClicked that will be called when the Ball hears a MouseEvent.CLICKED event. The run() method of this class (called from the Game class’ run() method) move the Ball up and down the screen as the ball “bounces” off the top or bottom, it’s speed increases. This “speed” is what we use for “score”. The faster the Ball, the more points the player scores.

This is where our problem arises. We need to dispatch an event back to our Game class that does two things: tells Game that a ball was clicked, and provide a score based on the speed of the Ball. We cannot do this with a regular Event, because we need to attach the score to message. Instead, we create our own Event that extends Event named “ScoreEvent” and send that event instead. Here is what what class looks like:

 

[cc lang=”javascript” width=”550″]package {
import flash.events.Event;
public class ScoreEvent extends Event{
public var score:int;
public function ScoreEvent(scr:int, type:String, bubbles:Boolean = false, cancelable:Boolean = false){
super(type, bubbles,cancelable);
score = scr;
}
}

}
[/cc]

ScoreEvent takes the same parameters as an Event class, but adds a scr which is used to set its score property. Before we do that, we call the Base Class with super(type, bubbles,cancelable); to make sure we initialize the MouseEvent as if it was a standard Event. Now Let’s go back and look at the code for the Game class’s ballClicked function;:

[cc lang=”javascript” width=”550″] public function ballClicked(e:ScoreEvent) {
trace(“Clicked:”+ Ball(e.target));
for (var i:int = balls.length-1; i >= 0; i ) {
if (balls[i] == e.target) {
removeChild(balls[i]);
balls.splice(i,1);
score+=e.score;
ScoreText.text = score.toString(); ;
}

}

}
[/cc]

Recall that we set-up the game class to call ballClicked when a CLICKED event was fired from Ball: tempBall.addEventListener(Ball.CLICKED, ballClicked); This function simply finds the Ball that was clicked on my looping through the balls array and trying to match the ScoreEvent’s target property to the Ball that fired it. When we find one, we increase score by the score set in ScoreEvent’s score property.

There are probably many other ways to solve this problem with the score, and other Events that could be used to listen to mouse clicks and fire events, but this tutorial simply illustrates how to create a custom Event and use it in your code.

Download the sample code here.

 

 

Leave a Reply