The first subject that I want to talk about is frame scripts. Many people fear them because they think that they are impure and noobish. However, even if that may be the case, you should still understand exactly what they are and how they work.

First, let's start with how frame scripts are actually implemented in ActionScript 3.0. First of all, any timeline that you write a frame script in will be assigned a class. This is because code only goes in classes in ActionScript 3.0. So, this means that frame scripts have to be placed in a class somehow. That class happens to be the class for the timeline that the frame script is placed on.

Now we have to wonder, how is the script actually stored in the class? As you might guess, it is stored as a method in the class. You might have seen the method names used when debugging, it is simply "frame" followed by the frame number. This is very simple.

However, there are a few exceptions here. Variables defined in frame scripts are not converted into local variables in the methods. They are instead converted into properties for the class. This is needed to ensure the semantics of the variables being persistent when referred to in other frame scripts. Similarly, simple functions are converted into methods in the class.

addFramescript

Now, you might wonder, how do these methods actually get executed? It is actually a very simple trick done by the compiler. The methods are registered as frame scripts by calling the undocumented method addFramescript. But when is this done? And by who? It is done by having the compiler inject the function call into the end of the constructor for the class.

The function addFramescript is a quirky beast, but it can be used by your own code if you are careful. It allows exactly one function to be called as a frame script per frame. It is one of the few methods in the player that takes a variable amount of arguments. It takes arguments pairs. The first value is the frame number to set the script for, using a zero based index. Or in other words, subtract 1 from the normal frame number. The second argument in the pair is a normal Function object. This second argument may be null. This is how you clear a set frame script. You may use any number of argument pairs in the call, this is in fact what the authoring tool does.

The function is quirky and can be a trouble to work with. Not only does it use zero based frame numbers instead of normal one based numbers, but it is also unstable. You absolutely must stop the timeline before calling it. Otherwise, you can easily get strange errors.

This undocumented function only exists in the MovieClip class, meaning that anything with a frame script has to extend MovieClip. If you have ever extended Sprite instead, but tried using a frame script, you may have figured this out, because you get an error if you do that, since the method doesn’t exist, yet Flash is trying to call it.

An example

The following code is how a simple timeline with two frames that each has a framescript and a movieclip will look once the compiler has injected the code for the framescripts.

package {

    import flash.display.*;
    import flash.events.*;

    public class MainTimeline extends MovieClip {
        public var myMc1:MovieClip;
        public var myMc2:MovieClip;
        public var myVar1:int;
        public var myVar2:int;

        public function MainTimeline() {
            addFrameScript(0, frame1, 1, frame2);
        }

        public function mcOnPress1(e:MouseEvent) : void {
            var myLocalVar1:int;
            trace(myVar1, myLocalVar1);
        }

        public function mcOnPress2(e:MouseEvent) : void {
            var myLocalVar2:int;
            trace(myVar2, myLocalVar2);
        }

        function frame2() {
            myVar2 = 0;
            myMc2.addEventListener(MouseEvent.MOUSE_DOWN, mcOnPress2);
        }

        function frame1() {
            myVar1 = 0;
            myMc1.addEventListener(MouseEvent.MOUSE_DOWN, mcOnPress1);
        }
    }
}