Rationale
The biggest complaint you hear about ActionScript 3.0 against its predecessor is that it’s too verbose. And one of the most verbose API’s in Flash today is the Eventing API.
Eventing in a single-threaded/asynchronous environment, such as Flash, is essential. And so, creating a powerful solution is of the up most importance. Adobe certainly delivered a powerful and robust system, but in this developers opinion, they got a little carried away somewhere along the line.
It’s very easy to demonstrate the verboseness of AS3 eventing with a little code snippet. Below I shall write two implementations of the same functionally, one in the older AS2 and the other in newer AS3. The code will listen for a button being clicked and then before the listener.
AS2 Version
myBtn.onRelease = function() {
trace("You clicked me! Now go away");
this.onRelease = null;
}
AS3 Version
myBtn.addEventListener(MouseEvent.CLICK, btnClickHandler);
function btnClickHandler(e:MouseEvent):void {
trace("You clicked me! Now go away");
myBtn.removeEventListener(MouseEvent.CLICK, btnClickHandler);
}
I really am a fan of the Events API in AS3, but when it comes to simple button interactions (like the above example) I think it’s clear that something needs to be fixed.
AVM1EventProxy
In response to this need I have written a few ActionScript 3.0 files that can be used to simulate the older AS2 style will still utilizing the ActionScript 3.0 events API; the days of onEnterFrame = function() {} are back!
Usage
I have setup the files in a manner that they can be incorporated into a project in four different ways.
- As Base Sprite/MovieClip Classes: Extends all your display objects from one of these two classes to inherit the AS2 event functionality.
Example:
import bustin.display.AVM1EventSprite
class MyApp extends AVM1EventSprite {
function MyApp() {
onEnterFrame = function() { trace("the bird is the word!")}
}
}
- Class mix-in: You already use a base Sprite/MovieClip class for all your projects? Well, that’s not a problem - simply use an include statement in your base classes to inherit all the AS2 event functionality.
Example:
class BobsAwesomeBaseSprite extends Sprite {
include "bustin/display/_AVM1EventProxy.as";
public function whoIsAwesome():String {
return "bob";
}
}
class MyApp extends BobsAwesomeBaseSprite {
function MyApp() {
onEnterFrame = function() { trace("the bird is the word!")}
}
}
- Timeline mix-in: Not a classes type of person; working in Flash Pro? - that’s cool too. Use an include statement in your frame script and code like it’s 2004 :).
Example:
include "bustin/display/TimelineEventHelper.as";
onEnterFrame = function() { trace("the bird is the word")}
stop();
- Proxy Object: Use a helper object to work with the AS2 style events.
Example:
import bustin.display.AVM1EventProxy
var e:AVM1EventProxy = new AVM1EventProxy(myBtn);
e.onRelease = function() {
trace("hey, what's the word?")
}
Callback Syntax
Currently, the implementation only anonymous functions. For example, in AS2 you were simply able to write this on the timeline:
function onEnterFrame() {
trace("fooo")
}
AVM1EventProxy only allows for this style:
onEnterFrame = function() {
trace("fooo")
}
Event Handler Arguments
You’ll notice that unlike ActionScript 3.0 event handlers, callbacks in AVM1EventProxy do not require any function arguments in most cases.
function eventHandler(e:Event) {} // an example of an AS3 event argument
onEnterFrame = function() {} // AVM1EventProxy version
Keyboard interaction is one case where you might like to know more about the interaction. So without an Event object being passed how can we find out which key was pressed? Well, AVM1EventProxy provides snapshots of the last event that you’re able to access via the callback like so ..
onKeyUp = function() {
trace(this.Key.charCode,"was released");
}
Notice that you can access the last Key event instance via the Key property in much the same was as you did in AS2.
Additionally, you can access mouse events via the MouseEvt property and focus events via the Focus property.
Keyboard Events
Keyboard events in ActionScript are most useful when they are being dispatched from the stage. For this reason AVM1EventProxy uses the stage for all keyboard events. You can seamlessly add keyboard callbacks with AVM1EventProxy without the display object being on the display list but they won’t start to fire until the display object has been added to the display list.
Currently Supported Callbacks
onMouseUp
onMouseDown
onMouseMove
onPress
onRelease
onClick
onEnterFrame
onKeyDown
onKeyUp
onRollOut
onRollOver
onKillFocus
onSetFocus
Disclaimer
BETA: Might contain bugs. Event behaviors might change/improve in the future.
Download
AVM1EventProxy.zip
Notes
Flash Professional will give you lots of warnings such as the one below … Ignore them.
Warning: 1090: Migration issue: The onMouseUp event handler is not triggered automatically by Flash Player at run time in ActionScript 3.0. You must first register this handler for the event using addEventListener ( ‘mouseUp’, callback_handler).