Two parts of the Flash Platform API shape nearly every ActionScript 3.0 program: one
event model, based on the W3C DOM Level 3 events, for everything from mouse clicks to
finished downloads; and the display list, a tree of display objects that the player
draws every frame. Both are in the flash.events and
flash.display packages.
EventDispatcher
Every object that sends events extends flash.events.EventDispatcher or
implements IEventDispatcher. Every display object does.
| Method | Does |
|---|---|
addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void | Registers a function to be called with the event object. A higher priority runs earlier; equal priorities run in the order they were added. |
removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void | Removes it again; useCapture must match the registration. |
dispatchEvent(event:Event):Boolean | Sends an event; gives false when a listener cancelled it with preventDefault(). |
hasEventListener(type), willTrigger(type) | Whether this object has a listener for the type; whether it or any object in the event’s path does. |
import flash.display.Sprite;
import flash.events.MouseEvent;
var button:Sprite = new Sprite();
button.graphics.beginFill(0x339933);
button.graphics.drawRoundRect(0, 0, 120, 40, 10);
button.buttonMode = true;
button.addEventListener(MouseEvent.CLICK, onClick);
addChild(button);
function onClick(event:MouseEvent):void {
trace("clicked at", event.stageX, event.stageY);
}
The event object
| Member | Meaning |
|---|---|
type | The event name, such as "click"; classes give these as constants, like MouseEvent.CLICK. |
target | The object the event was dispatched to: the clicked shape, the loader that finished. |
currentTarget | The object whose listener is running now, which differs from target during capture and bubbling. |
eventPhase | 1 capturing, 2 at target, 3 bubbling (EventPhase constants). |
bubbles, cancelable | Whether it takes part in the bubble phase; whether preventDefault() means anything. |
stopPropagation() | Stops the event moving to further objects, after the listeners of the current one. |
stopImmediatePropagation() | Stops it at once, even for the other listeners of the current object. |
preventDefault(), isDefaultPrevented() | Cancels the default behaviour, such as a typed character appearing; asks whether it was cancelled. |
clone() | Makes a copy, used when an event is dispatched again. A custom event class should override it. |
The event flow
An event dispatched to a display object that is on the display list travels in three phases:
- Capture – from the
Stagedown through each ancestor to the target’s parent. Only listeners added withuseCapturetrue hear it. - Target – at the target itself.
- Bubble – back up from the parent to the
Stage, for events whosebubblesis true, such as mouse and keyboard events.ENTER_FRAME,COMPLETEand most others do not bubble.
A listener added without useCapture hears the target and bubble phases.
Because of bubbling, one listener on a container can handle clicks on all its
children, reading event.target to tell them apart. An event sent to an
object that is not a display object on the list, such as a URLLoader, has
only the target phase.
Listeners and memory
A listener is a reference from the dispatcher to the function, and through it to the
object that owns the function, so an object with listeners on a long-lived dispatcher
(the Stage, a timer) is not freed. Removing listeners when they are no
longer needed avoids this. With useWeakReference true, the reference does
not keep the listener alive; but an anonymous function held only by a weak listener
can then be freed and stop being called.
Common events
| Constant | Name | Dispatched |
|---|---|---|
Event.ENTER_FRAME | enterFrame | To every display object at the start of each frame; the usual game loop. |
Event.FRAME_CONSTRUCTED, Event.EXIT_FRAME | frameConstructed, exitFrame | After a frame’s objects are created but before its frame scripts run; after its frame scripts (Flash Player 10). |
Event.ADDED_TO_STAGE, Event.REMOVED_FROM_STAGE | addedToStage, removedFromStage | When an object joins or leaves the list under the Stage; stage is null before the first. |
Event.COMPLETE | complete | When a load finishes. |
Event.RESIZE | resize | To the Stage when its size changes, with scaleMode set to NO_SCALE. |
MouseEvent.CLICK, MOUSE_DOWN, MOUSE_UP, MOUSE_MOVE, MOUSE_OVER, MOUSE_OUT, ROLL_OVER, ROLL_OUT, MOUSE_WHEEL, DOUBLE_CLICK | click and the rest | To interactive objects. ROLL_OVER and ROLL_OUT do not bubble; DOUBLE_CLICK needs doubleClickEnabled. |
KeyboardEvent.KEY_DOWN, KEY_UP | keyDown, keyUp | To the object with focus, usually listened for on the Stage; keyCode matches flash.ui.Keyboard constants. |
TimerEvent.TIMER, TIMER_COMPLETE | timer, timerComplete | From a flash.utils.Timer on each tick and after the last. |
ProgressEvent.PROGRESS | progress | During a load, with bytesLoaded and bytesTotal. |
FocusEvent.FOCUS_IN, FOCUS_OUT | focusIn, focusOut | When focus moves. |
Custom events
package com.example.events {
import flash.events.Event;
public class ScoreEvent extends Event {
public static const SCORE_CHANGED:String = "scoreChanged";
public var score:int;
public function ScoreEvent(type:String, score:int,
bubbles:Boolean = false, cancelable:Boolean = false) {
super(type, bubbles, cancelable);
this.score = score;
}
override public function clone():Event {
return new ScoreEvent(type, score, bubbles, cancelable);
}
override public function toString():String {
return formatToString("ScoreEvent", "type", "score");
}
}
}
// elsewhere, in a class that extends EventDispatcher or a display object:
dispatchEvent(new ScoreEvent(ScoreEvent.SCORE_CHANGED, points));
The [Event] metadata
tag on the dispatching class tells editors and the Flex compiler which events it
sends.
The display classes
| Class | Extends | Is |
|---|---|---|
DisplayObject | EventDispatcher | The base of everything that can be drawn: position, scale, rotation, alpha, filters, masks. |
Shape | DisplayObject | Vector drawing through graphics, with no children or mouse events. |
Bitmap | DisplayObject | Shows a BitmapData image. |
Video | DisplayObject | Shows video from a NetStream or camera. |
InteractiveObject | DisplayObject | Adds mouse, keyboard and focus events. |
TextField | InteractiveObject | Text to show or type in (flash.text). |
SimpleButton | InteractiveObject | A button with up, over, down and hit states. |
DisplayObjectContainer | InteractiveObject | Adds children. |
Sprite | DisplayObjectContainer | A container with graphics and no timeline; the usual base for a document class or a game object. |
MovieClip | Sprite | A sprite with a timeline of frames. Dynamic. |
Loader | DisplayObjectContainer | Loads a SWF or image and shows it as its child. |
Stage | DisplayObjectContainer | The root of the display list; one per player window. |
AVM1Movie, MorphShape, StaticText | DisplayObject | Made by the player only: a loaded ActionScript 1.0 or 2.0 SWF, a shape tween, static text from the authoring tool. |
Working with the display list
An object is drawn only when it is a child, directly or through containers, of the
Stage. The order of children is the stacking order, the last on top; the
player keeps the indexes packed, with no gaps and no depth numbers as in ActionScript
2.0.
| Member of DisplayObjectContainer | Does |
|---|---|
addChild(c), addChildAt(c, i) | Adds a child on top, or at an index; a child that already has a parent moves. |
removeChild(c), removeChildAt(i), removeChildren(from, to) | Removes children; the last from Flash Player 11. |
getChildAt(i), getChildByName(name), getChildIndex(c) | Finds a child. |
setChildIndex(c, i), swapChildren(a, b), swapChildrenAt(i, j) | Reorders. |
numChildren, contains(c) | The count; whether an object is in the subtree. |
mouseChildren | Whether children receive mouse events themselves. |
Display properties drop ActionScript 2.0’s underscores and use different scales:
x, y, width, height,
rotation in degrees, scaleX and scaleY where 1 is
full size, alpha from 0 to 1, visible, name,
parent, stage, root, mask,
filters, blendMode, cacheAsBitmap and
transform.
The Stage
The Stage is reached through any display object’s stage
property once it is on the list. It holds the player settings:
stageWidth, stageHeight, scaleMode,
align, frameRate, quality,
displayState for full screen, and focus. The main SWF’s
document class instance, or its main timeline, is the Stage’s first child and the
root of the objects under it.
package {
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
public class Main extends Sprite {
public function Main() {
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(event:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
addEventListener(Event.ENTER_FRAME, update);
}
private function update(event:Event):void {
// one step of the program each frame
}
}
}
Stage, then
set it up.Timelines and frame scripts
A MovieClip has a timeline: currentFrame,
totalFrames, currentLabel, currentLabels,
currentScene and scenes, and the methods
play(), stop(), gotoAndPlay(frame),
gotoAndStop(frame), nextFrame(), prevFrame(),
nextScene() and prevScene(). Frames are counted from 1, or
named by label.
Code typed on a keyframe in Flash is a frame script. Flash compiles all the frame
scripts of a timeline into methods of that timeline’s class (the document class, a
symbol’s linked class, or a class Flash generates such as MainTimeline),
named frame1, frame2 and so on, and has the constructor
register them with addFrameScript. That method of
MovieClip is not in Adobe’s documentation, but it works the same from
any code:
addFrameScript(frameIndex:int, script:Function [, frameIndex, script]…):void
The index counts from 0, so frame 1 is index 0, and passing null removes
a script. Each frame script runs when the playhead enters its frame, after the
frame’s objects are created.
public class Intro extends MovieClip {
public function Intro() {
addFrameScript(0, onFirstFrame, totalFrames - 1, onLastFrame);
}
private function onFirstFrame():void { trace("started"); }
private function onLastFrame():void { stop(); dispatchEvent(new Event(Event.COMPLETE)); }
}
Each frame of a playing SWF goes through the same order: enterFrame is
dispatched, new objects on the frame are created and frameConstructed is
dispatched, the frame scripts run, exitFrame is dispatched, and the stage
is drawn.