Let me start with a news flash for all you developers out there. The Timeline is not your enemy. The Timeline is your friend. The Timeline is your ally. Use the Timeline.
Developers are taught that attaching artwork to the Stage dynamically is better because you can keep the Timeline organized. This concept is sound on paper. In practice, however, it's not as useful as you would think.
In this case, I'm going to put my preloader smack dab in the
center of the Stage. Why? Because it saves me time and I don't have to calculate
the center of the display area. I don't have to write x = width * stageWidth/2 + someOffset or whatever. Flash has done all the math for me, so that I (or another
designer) can focus on positioning the preloader right where I want it.
My preloader is now centered on the Stage, and I've updated the Timeline for the preloader with frame labels (see Figure 1).

Figure 1. Timeline of the preloader including frame labels for each section
Oh dear, first the Timeline; now frame labels? Why would I ever do such a thing?!
Frame labels let me space out the animations. This saves me time because I don't need to keep notes that the animation first appears on Frame 2 and then begins to disappear on Frame 37. I know those activities occur at the frames labeled "IN" and "OUT."
By leveraging the Timeline for animation, artwork, and placement, I've freed myself of all the annoying (albeit simple) quirks of displaying the preloader on the Stage. Further, I've empowered designers to reskin the artwork easily. Do you want to add 10 frames to the "IN" animation? No problem. Do you need to change the preloader from green to purple? Sure, why not? Can you make the preloader look like a wine glass that fills up as the site loads? Can do.
In other words, the Timeline offers flexibility to modify the look and feel of a project without changing the fundamental purpose of the clip itself—to preload content.
My preloader must be designed to accommodate many different variations if it's to be easily reused. Here's the order of operations:
progress_mc is on the Stage.progress_mc to a
corresponding frame.progress_mc has reached the end of
its timeline (which correlates to 100% loaded), I'll tell the preloader timeline
to play "OUT."Pretty straightforward, right? Except at this point, you may be wondering how to tell when the "IN" and "OUT" animations have resolved. In the next part of this article, we'll take a look at how that works.
ActionScript 3 is centered around the concept of event dispatching. If you have previous experience working with ActionScript 1.0 or 2.0, you might already know a little bit about this process without even realizing it. Have you ever written code like this?
var mouseListener = new Object();
mouseListener.onMouseDown = function() {
trace("The mouse button is down.");
};
Mouse.addListener(mouseListener);
In the code above, the mouseListener object is listening for an event (onMouseDown) from the Mouse class. When that event occurs—which we know happens when the user presses
the mouse button down—Mouse will dispatch an event, which it
calls onMouseDown.
Anything listening for that event—in this case, mouseListener—will fire
its corresponding onMouseDown().
The beauty of event dispatching is that multiple objects can listen for the same event and react differently as the event occurs. The following example illustrates how two listeners can respond to the same event:
var mouseListener1 = new Object();
var mouseListener2 = new Object();
mouseListener1.onMouseDown = function() {
trace("the mouse button is down.");
};
mouseListener2.onMouseDown = function() {
trace("1+1=" + (1+1));
};
Mouse.addListener(mouseListener1);
Mouse.addListener(mouseListener2);
Now Mouse has two listeners. Each is listening for
the same event, but doing something different when the event occurs. In the
example above, both listeners are tracing messages to the Output panel, but
there's no reason mouseListener1 couldn't do one thing while mouseListener2 does
something wildly different.
When you get into object-oriented programming, specifically building classes, this is really great because classes can handle the same events independent from one another without "knowing" what the other classes are doing.
Let's back away from code for a second. Pretend for a second that your code is a fast-food restaurant (The ActionScript Café), the user (customer) is a patron, and s/he is hungry (mmm, that smells good).
The customer would like to order something. Now there are two ways your restaurant can go from here:
In programmer-speak, Scenario 1 is the old-fashioned programming methodology you're used to. Bugs are difficult to squash because it's hard to tell keep track of what's happening at any point.
Scenario 2 is much more ideal. If there's a problem with the food, you need to look to fix the Cook class. If there's a problem with the cash flow, it's in the Cashier class. If there's a problem with both, maybe it with the TouchScreen class. Any way you slice it, the code is explicitly more organized and thus easier to manage.
Let's talk about how events come into play in ActionScript
3.0—and, more specifically, in regards to building this preloader. In
ActionScript 3 (and even ActionScript 2), you can define your own events.
Furthermore, movie clips extend Event Dispatcher, meaning that movie
clips can dispatch events in much the same way that the Mouse example above
does.
Why is that strategy useful? I'll show you. Let's use the preloader as an example. If you take a look back at Figure 1, you'll notice there's code on the Timeline at the "IN_IDLE" frame label:
import com.bigspaceship.events.AnimationEvent; dispatchEvent(new AnimationEvent(AnimationEvent.ANIMATE_IN)); stop();
The import statement grabs an external class (I'll
cover that part in a minute) for use in the Timeline. In this case, it's my
custom event, AnimationEvent. I'm going to dispatch AnimationEvent.ANIMATE_IN.
That event is a simple string. Similar to knowing that the mouse is down by
virtue of the occurrence of an onMouseDown event in ActionScript 1.0,
my listeners will wait for AnimationEvent.ANIMATE_IN and know that the
Timeline has finished animating the section with the "IN" frame
label.
The code is very similar for the "OUT_IDLE" frame label:
import com.bigspaceship.events.AnimationEvent; dispatchEvent(new AnimationEvent(AnimationEvent.ANIMATE_OUT)); stop();
By using dispatchEvent,
I know when the Timeline has resolved the "OUT" animation. I call
these event hooks. While "IN" and "OUT" are
animating, my code simply waits and listens. Once I've reached an event hook, I
can program the logic to proceed with the preloading process.
For more information about event handling, check out Trevor McCauley's article, Introduction to event handling in ActionScript 3.