Internet / Software Applications

Macromedia Flash MX 2004 ActionScript Programming Tutorial

Using Listeners

Listeners are simply objects that listen for and respond to user-initiated events. The events are communicated by other objects with a built-in ability to broadcast them. In Flash MX, the Key class, Mouse class, MovieClipLoader class, Selection class, Stage class, and TextField class all have a built-in ability to broadcast certain specific events. For example, the Key class broadcasts the onKeyDown and onKeyUp events. The Mouse class broadcasts the onMouseDown, onMouseMove, and onMouseUp events, which can be “handled”, or used, by a MovieClip object listening for the events.

The purpose of a listener is to listen for these “broadcasts” and perform actions as a result. Any object can be a listener—a button, a movie clip, or a new object you create. Before we describe how to create and use a listener, let’s compare this new event model with the event handling you’ve been using so far:

on(release) {

getURL(“http://www.macromedia.com”);

}

Above, an on(release) event handler is attached to a button symbol and used to open the Macromedia home page when the user clicks (releases) the mouse button. Using the new event model in Flash MX, this code can be rewritten as follows:

mybutton.onRelease=function() {

getURL(“http://www.macromedia.com”);

};

The action to be performed is now placed in a function that uses the onRelease event automatically broadcast by the Flash Player. Some events aren’t broadcast by a specific object, but by the Flash Player—one of these is onRelease. These events can be used by any of several objects—most often the Button and MovieClip objects, which can use the largest number of events. In the case above, the Button object “myButton” is handling (using, or executing an action as a result of) the onRelease event broadcast by the Flash player. You could also have a movie clip use the event, by replacing the name of button with the movie clip.

What difference does it make? For this example, not much. But the broadcaster/listener event model is more flexible than using event handlers, since multiple pieces of code can listen for the same event and perform different actions. Several listener objects can receive events from one broadcaster, or one listener can receive events from several broadcasters and perform the same actions.

As an example from our Asteroids game, you saw that we had to include a movie clip (our “laser” clip) within a movie clip (our “laser_clip” clip) in order to add an event handler (on(enterFrame)) to the “laser” movie clip. This is because, prior to Flash MX, there was no way to add an event handler to a movie clip created at run-time using the attachMovie method.

All movie clips “listen” for Key, Stage, and Mouse events automatically, and movie clips and buttons automatically listen for movie clip and button events, respectively. This means buttons and movie clips don’t need to be registered as listeners to listen for their built-in events. So, instead of using our “movie clip within a movie clip” to add an on(EnterFrame) event handler to our “laser” movie clip, we could have used only the inner “laser” movie clip (with a linkage ID of “laser”) and done something like the following:

//Attach a duplicate of the laser movie clip to the gun_mc movie clip instance

_root.gun_mc.attachMovie(“laser”, “laser1”, 0);

//Specify the actions for the onEnterFrame event

_root.gun_mc.laser1.onEnterFrame=function() {

_root.gun_mc.laser1._y -= 10;

};

When the above code is placed into Frame 1 of the main timeline, it attaches an instance of the laser movie clip to the gun movie clip, automatically firing off the laser from the gun and moving it vertically across the stage. For our Asteroids game, we’d add code to attach an instance of the clip each time the gun is fired, but this demonstrates the advantage of the broadcaster/listener event model.

Because movie clips automatically listen for events broadcast by a MovieClip object, we didn’t have to create a listener to “listen” for the onEnterFrame event. But we could have, if we’d wanted to create a new object to listen for the event.

Because a listener is an object itself, you can create a listener for virtually any event being broadcast. You do this by declaring a new object:

var myListener = new Object();

Or: var myListener:Object = new Object();

Once you’ve created a listener, you create methods for it that are tailored to the object it’s listening for. The methods are simply the events that the broadcasting object automatically broadcasts and that you want to use. For example, if you want to “listen” for a user pressing any key on the keyboard, you’d assign the onKeyDown event to the listener’s function:

myListener.onKeyDown = function() {

getURL(“http://www.macromedia.com”);

};

Remember that onKeyDown is one of the events that the Key class automatically broadcasts. Now, anytime the movie detects the user pressing a key (any key), the getURL action will be executed, opening the Macromedia home page. In a few minutes, we’re going to use this to control our gun movement in our Asteroids game.

Once you’ve created a method for a listener, you need to assign the listener to the object broadcasting the events—this is referred to as “registering the listener with the object”. You do this using the addListener method:

Key.addListener(myListener);

The line above “registers” the myListener listener object with the Key object, the object broadcasting the event we want to listen for. In other words, our listener object now knows what to pay attention to.

If we ever want to stop “listening” for an event (or stop executing actions when the event is broadcast), we can “unregister” the listener using the removeListener method:

Key.removeListener(myListener);

To see how listeners work, we’re now going to create one to listen for the onKeyDown event being broadcast by the Key class. In other words, we’re going to “listen” for keys being pressed. We’re going to use the listener to let Flash know when the user has a key down, and stop moving the gun when the key is up (or no longer being pressed):

  1. Select the gun_mc movie clip on the stage.
  2. Add the following code to an onClipEvent(load) handler to create a new listener:

onClipEvent(load) {

var KeyIsPressed = false;

//Create a new listener object to listen for user interaction

keyListener = new Object();

//Add the onKeyDown method to the listener object

keyListener.onKeyDown = function() {

KeyIsPressed = true;

};

//Register the keyListener object with the Key object

Key.addListener(keyListener);

}

The only action our listener performs is to toggle the variable KeyIsPressed. When the user presses a key on the keyboard, the Key class automatically broadcasts the onKeyDown event. If no listener exists for it, the event is ignored. What we’ve done is created a listener to listen for the event and, as a result, change the value of the KeyIsPressed variable to true.

  1. Wrap your current onClipEvent(enterFrame) code into the following if statement:

if (KeyIsPressed) {

KeyIsPressed = false;

}

The entire onClipEvent(enterFrame) handler should now look like this:

onClipEvent(enterFrame) {

if (KeyIsPressed) {

KeyIsPressed = false;

//Determine which key is pressed

var whichKey = Key.getCode();

//move the gun

switch (whichKey) {

case Key.LEFT:

_x -= 25;

break;

case Key.RIGHT:

_x += 25;

break;

case Key.SPACE:

_root.numShots++;

this.attachMovie(“laser_mc”, “laser_mc” + _root.numShots, _root.numShots);

break;

}

}

}

If a key is being pressed (true), as detected by our listener, the code is executed, with the first line immediately resetting the KeyIsPressed variable to false.

  1. Save and test the movie. Use the left and right arrow keys to move the gun. When you release a key, the gun should stop moving. The next time the movie clip enters a frame (which happens within a split-second), the KeyIsPressed variable is reset to false, so the code for making the gun move isn’t executed. It won’t be executed again until our listener “hears” a key being pressed and resets the value of the variable to true, thus executing the code in the switch statement.

At this point, you can click the play button and try blowing up some asteroids before they blow up your ship. You’ll probably need to tweak the positions of the original asteroid (asteroid_mc) and the ship’s hit target (hit_mc inside of ship_mc), as well as the speed of the gun (by changing the movement increments for the left and right arrow keys). If you get frustrated, as the developer you have the luxury of commenting out the code that blows up the ship.

Our game is by no means perfect—or even approaching a professional-quality video game—but our hope is that each of the exercises you’ve followed to produce it has given you a good foundation in Flash programming. In the next section, we’ll finish our game by adding a feedback form. Then we’ll mention a couple of other techniques that you can add to your Flash programming toolbox.