ActionScript.org Flash, Flex and ActionScript Resources - http://www.actionscript.org/resources
Actionscript and timelines
http://www.actionscript.org/resources/articles/943/1/Actionscript-and-timelines/Page1.html
Henrik Andersson
I write actionscript as a hobby and have gotten very good at understanding the finer points of the language and the platform. I generally hang out on IRC and the forums if you want to discuss something.
 
By Henrik Andersson
Published on November 6, 2009
 
A deep down explanation of exactly how timelines, framescripts and actionscript interact.

Introductions
This text will reveal the secrets about how timelines and scripting interact. When you are finished reading this, you will have a great understanding of the issues related to timelines and why they exist.

Understanding frame scripts

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.

[as]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);
}
}
}[/as]

Timeline instances

The other subject that I want to discuss is timeline instances. As you should know if you are reading an advanced text like this, instances can have assigned instance names. But what is exactly an instance name?

An instance name is really only one thing; it is the value of the "name" property of the DisplayObject class. It allows you to get a reference to the instance using getChildByName from the DisplayObjectContainer class.

However, for authoring time set instance names, things suddenly get more interesting. When the Flash Player finds an instance with a set name on a timeline, it does you a service, even if you don’t want it. The player tries to set a property on the timeline object with the same name as the instance name. If nothing else was done, this would give a runtime error.

However, the authoring tool by default defines this property on the class for you. This is possible to disable in the publishing settings. Doing this can be useful if you need the definition to be done in a special way, for example, as a base type or in a base class. However, if you turn this option off, you are responsible for defining all these properties in all of your classes in the full project. Note that I used the expression "your classes". By that I intentionally exclude classes that Flash writes for you. Flash is always declaring the property in those classes.

This is quite a large undertaking and should not be done unless you are prepared on doing the work. Do note that if you try to define the property yourself when Flash also is defining it for you, you end up with a compiler error. After all, there is a duplicate property definition. On the flip side, if no one defines the property, you will get a runtime error when the player tries to set the property.

Moving the timeline

When you move the timeline, the player does a lot of things for you. One of these things includes creating new instances and putting them on the display list of the timeline. It also moves existing instances. However, there are some very common gotchas here.

The first gotcha is that the instance simply isn't created until it is needed. It is created when the keyframe is shown. This means that it is impossible to access an instance on a different frame, because the instance simply doesn't exist at this point.

Now onto the other gotcha. When does the player create a new instance? Obviously it does it if there isn't an instance to begin with. But it also does this at some keyframes. I do not myself fully understand exactly what the exact conditions are. But I do know one thing, if you can use a different instance name in the authoring tool compared to the previous frame, you got a new instance.

But what is this gotcha then? It is actually quite simple. It is mistakenly assuming that the old instance is still the instance that you see. For example, thinking that any event listeners that you have added to the old instance will apply to the new instance. This can be a potentional memory leak if you do not account for the possibility of the instance you have a reference to no longer being on the display list.


Symbol contents, components and finishing words

With all this talk about how instances behave, it is now time to explore how the content of an instance works.

For a MovieClip symbol, it is fairly simple. Everything with an instance name is added to the movieclip instance's own display list. However, what is done with the actual drawn shapes? Is it added by just drawing stuff with the Graphics object associate with the timeline? No, it is added as Shape objects that are added to the display list of the movieclip.

Graphics type symbols are never a real instance on their own in the final SWF file. They are just named groups in the authoring tool. Their content is placed at each spot they appear during publishing. This explains why there are so few options available for them; they don’t have a place for those options in the swf file.

The last symbol type, buttons, is very strange. They are not obeying the normal container system at all; instead, they show one of three different states, using a fourth sate as the clickable area. This is due to how the buttons are saved in the swf file, exactly like that, four different states.

The mysteries of components

Components are mysterious things that nobody actually understands. Well, at least that's the picture most people have about them. But they are not that hard in reality. However, this is not a tutorial in how the components work. I only want to briefly mention one relevant part about them, the component properties.

The component properties can be used to set values on the component from the component inspector. This includes things like the label on buttons and so on. But how is these settings saved?

It is actually quite similar to how the frame scripts work. The compiler injects extra code at the end of the constructor and/or the frame script for the frame to set the properties at runtime. Depending on your version of Flash, it may do the setting of the properties inline or in a separate method, but the point is that it is done at the end of the constructor.

Obviously, if you try to set the properties yourself in the constructor, the values that you set will indeed be set, but only for a limited time. The injected code will blindly overwrite the values that you have set. My advice here is simple: don't set any component properties at authortime if you run into this issue.

Finishing words

In conclusion, a lot of the mysteries that makes it hard for people to work with timelines in Flash actually stem from a lack of knowledge about the topic. These topics are simple enough to explain that I managed to do it within this short text, but they are not explained anywhere else, not in the manual and not online either. By writing this text, I hope that you, the reader, will have an easy time working with Flash instead of having to figure out all of this on your own like I did.