(last edited on April 29, 2014 at 1:30 am)
For a while, I’ve been wondering if there was a better way of catching events from MovieClips in an object-oriented context. If you use the “onEvent” hooks in MovieClip, they store only the address of your function. The way I did it in Prove It was by (taking deep breath) creating a static method in a special MovieClip wrapper class that used the this keyword as the key in a hashed array for looking up registered instance references…
In other words, something like this:
class ClipWrapper // Dave Seah's Magic Event Manager static var lookup:Array; static var ON_PRESS_EVENT = 10; static var ON_RELEASE_EVENT = 11; static function RegisterClip(clip:MovieClip, obj, method:Function) { var execObj = new Object(); execObj.obj = obj; execObj.method = method; lookup[clip]=execObj; } static function DispatchEvent (clip:MovieClip, eventType:Number) { var execObj = lookup[clip]; var obj = execObj.obj; var method = execObj.method; method.call(obj, eventType); } private var clip:MovieClip; // wrapped clip function ClipWrapper() { clip = _root.createEmptyMovieClip(); RegisterClip(clip,this,HandleClipEvent); clip.onPress = function () { ClipWrapper.DispatchEvent (this, ON_PRESS_EVENT) } clip.onRelease = function () { ClipWrapper.DispatchEvent (this, ON_RELEASE_EVENT) } } function HandleClipEvent(eventType:Number) { switch (eventType) { ... } } }
This works around the problems with using the MovieClip event handlers onPressEvent or what have you…they do not execute in an object-context, so none of the instance variables are available. However, when the callback is executed, the anonymous function’s this
is set the movieclip that triggered the event. And since we have a static method defined as ClipWrapper.DispatchEvent()
, we can call it so it can look up the object that has registered to receive events, then call the method & restore the object context.
I thought that was pretty cool, but registering and de-registering objects in the array is a bit slow when you get to 500 or so objects (the hashing slows way down). But in a ClipWrapper managing only a few clips, lookup should be relatively fast.
Other people must have figured this out, but I wasn’t finding much online. So this seemed to indicate to me that there was a far easier way of doing it that I just was missing. After reading Essential ActionScript 2.0, I realized that this was the Mouse.AddListener
function. You can track MouseUp, MouseDown, and MouseMove and roll-your-own event management this way. And Listeners are completely object friendly, unlike Callbacks.
There might still be an advantage to the way I was doing it before for making use of the built-in event masking that happens when you nest movieclips, so I’m continuing to look into it.
Extending a MovieClip directly might also get away from this problem, but I don’t like writing code that requires you to establish class linkages in the Flash Library. A foible, I know.
For the current game project, I’m using Mouse.AddListener. The interactivity is pretty limited, so I don’t anticipate having to roll things together. I’m curious what kind of benchmark improvement might occur by using a native code dispatch mechanism.
0 Comments