Big MovieClip “Duh”

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.

Share 'Big MovieClip “Duh”' on Email Share 'Big MovieClip “Duh”' on Facebook Share 'Big MovieClip “Duh”' on Twitter Share 'Big MovieClip “Duh”' on Google+ Share 'Big MovieClip “Duh”' on Delicious Share 'Big MovieClip “Duh”' on Digg Share 'Big MovieClip “Duh”' on reddit Share 'Big MovieClip “Duh”' on StumbleUpon Share 'Big MovieClip “Duh”' on Wordpress Share 'Big MovieClip “Duh”' on Instapaper
Posted in Computers and tagged , . Bookmark the permalink.

Comments are closed.