
A Closer Look
Documenting the Undocumented
In the initial example using the MovieClip.addFrameScript() (noted above), all I wanted was some way to have an animation play once and stop. As soon as the playhead reached the last frame, it jumped to a function named in the second parameter of the addFrameScript() method. However, I didn’t do much by way of clarifying that. So I’d like to start with a general view of the method shown in Figure 1:

Figure 1: Structure of the addFrameScript() method
Oddly, the trick to using the method effectively is not just in the ending frame to fire the function, but also in the starting frame. In looking around, one thing I found is that the method can have multiple trigger frames that launch a function. The following shows the format:
mc.addFrameScript(n1, func1, n2, func2, n3, func3);
Each trigger frame is the frame number in the movie clip minus 1. However, when you have multiple triggers, you want to play the movie clip from some starting point other than the one that fires the function. To be purposeful, I believe that using this method must take advantage of multiple animations that can be generated in a single movie clip either at different starting points and/on on different layers. In other words, anywhere in the movie clip. The general setup for this kind of functionality looks like the following:
mc.addFrameScript(n1, func1, n2, func2);
mc.gotoAndStop(1);
. . . .
mc.gotoAndPlay(seqBegin);
In this case the parameter, seqBegin is where the animation segment begins. It plays until it hits the trigger frame that fires the function that stops the animation or causes some other action.
Adding an Exoskeleton
When placing code on the Timeline or inside the MovieClips themselves, the code is hidden and unavailable to the larger structures provided by Design Patterns. So, I continue to think of the code in terms of an exoskeleton that can reach all parts of the MovieClip objects in the Library and at the same time be available for ActionScript 3.0 in ActionScript files. In order to illustrate something useful with the multiple function addFrameScript() method, I decided to continue with an example for the bellicose Wrong Way Warrior. I create three animations for an exploding grenade, rocket and mortar. The only difference is in the size of the explosion, but the animations could be as complex or simple as desired.
Taking an eight-sided star drawing, I placed it into a graphic symbol. Then, I created a MovieClip giving it the class name Boomer. It used motion tweens to expand the graphic star from small to large. Depending on the weapon, the explosion varied. Figure 2 shows the MovieClip’s timeline with the motion tweens:

Figure 2: Animated Explosions in MovieClip
Each tween was either 5 or 6 frames — explosions are quick and short. Further, each started in a different position on the timeline and on a different layer. Given that the same symbol was re-used on all three, I suppose I could have put them all on the same layer, but it was clearer to place the tweens on separate layers.
Once that was done, all I had to do was to write a script that made use of the animations in the MovieClip object. Because I set it up for Export for ActionScript, I was able to address each in turn. (The example is a test bench, and they are not integrated into the Wrong Way Warrior or connected to sounds.) The following script shows how the ActionScript controlled the MovieClip’s playhead movement.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | package { import flash.display.MovieClip; import fl.controls.Button; import flash.events.MouseEvent; public class AddScript extends MovieClip { //Create MovieClip instance private var boomer:MovieClip=new Boomer(); //Starting frame private const THROW_GRENADE:uint = 1; private const FIRE_ROCKET:uint = 7; private const LAUNCH_MORTAR:uint = 12; //Frame to trigger function (minus 1) private const GRENADE:uint=(6-1); private const ROCKET:uint=(11-1); private const MORTAR:uint=(17-1); //UI private var grenade:Button=new Button(); private var rocket:Button=new Button(); private var mortar:Button=new Button(); public function AddScript() { setUI(); boomer.x = 250,boomer.y = 200; boomer.addFrameScript(GRENADE,ceaseFire, ROCKET,ceaseFire, MORTAR,ceaseFire); boomer.gotoAndStop(1); } private function setUI():void { grenade.x = 10,grenade.y = 20; grenade.label = "Throw Grenade"; grenade.addEventListener(MouseEvent.CLICK,fireWeapon); addChild(grenade); rocket.x = 10,rocket.y = 50; rocket.label = "Fire Rocket"; rocket.addEventListener(MouseEvent.CLICK,fireWeapon); addChild(rocket); mortar.x = 10,mortar.y = 80; mortar.label = "Launch Mortar"; mortar.addEventListener(MouseEvent.CLICK,fireWeapon); addChild(mortar); } private function fireWeapon(e:MouseEvent) { addChild(boomer); var weapon:String = String(e.target.label); switch (weapon) { case "Throw Grenade" : boomer.gotoAndPlay(THROW_GRENADE); break; case "Fire Rocket" : boomer.gotoAndPlay(FIRE_ROCKET); break; case "Launch Mortar" : boomer.gotoAndPlay(LAUNCH_MORTAR); } } private function ceaseFire():void { boomer.gotoAndStop(1); removeChild(boomer); } } } |
In setting up the constants for the values where the timeline position would fire the functions, I used expressions to remind us that the addFrameScript() function uses a zero-base numbering system for frame reference. That is, the first frame is zero (0), and all of the rest are the frame number minus 1.
Why Undocumented?
It always makes me nervous to get too close to an undocumented feature in ActionScript 3.0. That means at any moment the method will be deported like an unwanted immigrant. However, the method has been around since Flash CS3 and I’ve seen it referenced in some Flex listings. Why it remains undocumented is a mystery to me, but I hope that they decide to keep it or replace it with a documented method that allows direct access to the timeline with code that is in an ActionScript 3.0 file in either Flash or Flex (Flash Builder).
As an alternative to onEnterFrame(), this method is much cleaner and far less processor intensive. It patiently waits until the playhead reaches the trigger and then launches the appropriate function. Compare this to the onEnterFrame() method that keeps running back and fourth asking, Are we there yet? like some annoying kid in the back seat.
In the meantime, the addFrameScript() method is quite valuable for developers who want to free themselves from the limitations of script on the Timeline and keep all of the advantages of controlling the play on the Timeline. If you feel the same as I do, we can launch a whining campaign at Adobe—just like the annoying kid in the backseat.

The A Closer Look: Using MovieClip.addFrameScript() by William B. Sanders, unless otherwise expressly stated, is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.
Related posts:

Bill Sanders
Thanks for explaining this cool feature which I had no idea existed. I can see it being very useful when dealing with animated MovieClip assets … eg. a game where you want to know when the player’s ship has finished blowing up. The one thing that seems awkward is having to reference the exact frame number.. wish there was a way to use a frame label instead.
My own project is going to be very dependent on being able to make things happen like this. I haven’t tried to write the code yet, but I was assuming I could make the code finish playing an animation and then jump to a function using event dispatches. Is this not the case? Thanks.
Barbara
Hi David, You can do the following if you know that certain labels exist in a movie clip.
The following class extends an MC on the stage that has two labels called ’start’ and ‘end’ on the tween.
Now you can safely modify the tween lengths etc. knowing that the code references the labels and not explicit frame numbers.
Hi David & Barbara,
@David–I couldn’t improve on Chandima’s comment except to add when when using variables you’d want to change the constants to variables. Like you, I’ve only recently learned of this method even though it’s been out for a few years.
@Barbara–Essentially, the MC playhead is acting like a trigger. As soon as it hits the frame, the function is going to be called and it doesn’t matter what you put in the function. I can imagine an endless number of scenarios for this method.
Kindest regards,
Bill
Hi Bill and Chandima,
Thanks for the tip about the playhead. I figured out how to use addFrameScript() with an event dispatch and thus avoid having a script on the timeline, and it certainly is cool! I made a little app that has 3 colored balls moving across the stage. When the red one gets to the end of its timeline, it triggers the green one etc. Here’s the URL: http://bitsong.com/forPosting/dispatchTest/dispatchTest.html
Here’s some of my code: I include Main.as and one of the colored ball classes, RedBallContainer.as Your blog is a great place to get exciting new ideas! Thanks.
Barbara
Hi, David!
Do you happen 2 know if there are any other undocumented function like the one u described?