Accessing EnterFrame Events in non-Display Objects

Once in a while you want to be able to have an object carry out actions on a frame interval. This is simple to accomplish when you’re working with a DisplayObject, because you can just subscribe to its ENTER_FRAME event directly, but there are times when you need this functionality in a non-display object without passing around a reference to a movieclip. In some cases, you can get by with using a Timer or interval, but this is often not ideal because you have no guarantee how often the event will fire in a single frame (a timer can fire multiple times, or not at all depending on how it synchs up with a frame cycle).

Turns out the solution is ridiculously simple: Just create a flash.display.Shape instance in your object, and subscribe to its ENTER_FRAME event. DisplayObjects do not have to be on the stage to generate enterFrame events.

Grant Skinner

The "g" in gskinner. Also the "skinner".

@gskinner

12 Comments

  1. I typically use Shape; its lighter and still receives the enterFrame event.

  2. I’ve been doing a similar thing in the form of Thread class. In reality just a Shape class (like senocular suggested) that keeps firing RUN events until it’s stopped.

  3. I thought you might have subscribed to gSprite? ahh, but no….the lowercase g. what was I thinking!!

  4. Why not just use a DisplayObject instance? That’s the most ancestral (i.e., smallest and least complex) class that dispatches the ‘enterFrame’ event.

  5. Mike – DisplayObject is an abstract class, and cannot be instantiated. Senocular is correct that Shape is the lightest-weight object to use for this purpose, I’ve updated the entry to reflect this.

  6. Neat – didn’t realize that there were disadvantages to using a Timer for this sort of thing.

  7. David,

    Timer and EnterFrame are based on different ideologies. Enterframe is frame based and runs code every frame while a timer event happens after x milliseconds.

  8. Good tip! I just tried it.

  9. Actually, everything in Flash is tied to the frame. Timer events are not guaranteed to execute every X ms, but rather as close to every X ms as the player is able to do it (which often is not that close).

  10. Ray Greenwell June 29, 2007 at 1:02pm

    Just a note with this approach:

    ENTER_FRAME works like this because it seems to be an optimization internal to the flash player. According to the official documentation a DisplayObject should not receive the ENTER_FRAME event unless it’s on the hierarchy. Depending on this behavior may be dangerous.

    Also: due to this optimization, any DisplayObject that has any ENTER_FRAME listeners will not be garbage collected, even if all normal references to the object are cleared. You have been warned.

  11. “Mike – DisplayObject is an abstract class, and cannot be instantiated.”

    Whoops, so it can’t. I assumed it would be okay since there are no true abstract classes in ActionScript. I see they made a pseudo-abstract class by throwing an ArgumentError. (I would have thought IllegalOperationError would be more appropriate….)

    I so hope they add an “abstract” keyword to AS4.0. Approaches like this one make it clear that, even though they (bizarrely) removed the ability to make private constructors, they still want to be able to make uninstantiatable classes. An “abstract” keyword would be much more elegant than this kind of run-time exception throwing.

Leave a Reply

Your email address will not be published. Required fields are marked *