Tutorials, extensions, and source files for ActionScript, Flash, and other Adobe products.

 

Preloading in Flash

Examples provided in Flash MX 2004 format

Introduction

Preloaders, the hardest of the simplest tasks in Flash. Simply put, preloaders are custom-built indicators that inform the viewer that content is being loaded into the Flash player. As easy as they sound implement, creating one that works effectively and correctly can often be a quite frustrating task. This tutorial should help explain the ins and outs of preloaders and help you be better equipped to deal with them on your own.

Basic Kinds of Preloaders

There are generally two kinds of preloaders:

  1. Preloaders that load the main, current Flash movie and
  2. Preloaders that load additional, external content within an already loaded main movie

When loading the main movie, you are using a preloader that exists within the same movie that you are attempting to load. Because of this, these kinds of preloaders should be (in terms of file size) as small as possible since the preloader itself has to load prior to the rest of the movie before it can even start to function.

When loading external content, such as other Flash movies (swf files) or images, preloader size isn't as important. This is because the preloader for that external content does not exist within the content. Instead, it exists within the current Flash movie which should already be completely loaded, preloader and all.

The complexity of a preloader can range anywhere from a simple, static waiting message to a dynamically updated animation that reflects the status of the content loaded. The difficulty of implementing a preloader obviously increases with complexity. Preloader progress bars are the most common form of preloaders which show a progression bar that displays how much content has been loaded visually.

progressbar component
Flash MX 2004 ProgressBar Component

Simple Loading Complete Preloaders

The easiest kinds of preloaders are static preloaders used to load the movie in which they exist. For these preloaders, all you need to do is stop the movie on a preloader screen, usually the first frame of the movie, and keep it there until you are able to determine that the movie has been completely loaded into the Flash player. The two basic ways to perform this check is by either comparing the _framesloaded property with _totalframes, or comparing getBytesLoaded() with getBytesTotal().

_framesloaded and _totalframes are properties each timeline or movie clip instance has to indicate how many of its frames has loaded and how many exist in total, respectively. When these equal, loading is complete. Similarly, getBytesLoaded() and getBytesTotal() exist for each timeline or movie clip instance and return a numeric value that indicates the loaded or total size of the clip in bytes. When those values are equal, loading is complete.

Note: Preloaders and Scenes

There is no way to load individual scenes separately. All scenes are loaded with the main movie so creating separate preloaders for individual scenes is not really an option. If you would like to prevent all of your movie from being downloaded at once, you can use separate external Flash movies which can be loaded into the main movie on demand.

Example 1

preview

Using an onEnterFrame event handler, a continuous check can be performed to look for equalities of _framesloaded and _totalframes, or getBytesLoaded() and getBytesTotal() within _root (the main timeline) on frame 1 of the main movie. When equal, the movie is loaded. Then, the onEnterFrame check can be cleared and the movie played.

Code using _framesloaded and _totalframes.

stop();
onEnterFrame = function(){
	if (_root._framesloaded == _root._totalframes){
		delete onEnterFrame;
		play();
	}
}

Note: Example Code Comments

Though not shown here, all ActionScript in the example files is fully commented.

Code using getBytesLoaded() and getBytesTotal().

stop();
onEnterFrame = function(){
	if (_root.getBytesLoaded() == _root.getBytesTotal()){
		delete onEnterFrame;
		play();
	}
}

Note: Simulating Downloads in Flash

You can preview your movie as though it were being downloaded from the internet by using Flash's Simulate Download option for movie testing (hit CTRL + ENTER twice when testing a movie or use View > Simulate Download).

Though this can be a tool to help you see how your preloaders may function in more practical circumstances, results may still differ between what you see in Flash and what you might get in a browser.

Progress Indicating Preloaders

With larger Flash movies, simply being told to wait can be nerve-racking for a viewer, especially without knowing how much more waiting will have to be done before the movie begins. Using a progress indicator in your preloader can help ease that pain, showing just how much longer the movie needs to complete the loading process.

Most preloaders showing progress are based on the percent of the movie loaded--anywhere between 0 to 100% where 100% is completely loaded. This percent is derived from dividing the amount of the movie loaded by the total possible. When dealing with amount here, its usually with bytes and not frames, using getBytesLoaded() and getBytesTotal() in favor of _framesloaded and _totalframes. This is because frames can have different sizes and take longer to load. Basing a percent loaded on frames can cause jumps and areas of slow loading despite the fact that the same amount of information (bytes) is being loaded.

var percent_loaded = _root.getBytesLoaded()/_root.getBytesTotal();

The percent_loaded variable will be a value from 0 to 1 (1 equals 100%) based on how much of _root is loaded. This value can then be used for your preloader.

Note: The Bandwidth Profiler

Flash provides you with a bandwidth profiler (View > Bandwidth Profiler) that visualizes the download performance of your tested movies. It shows how much data is sent for each frame according to the download speed settings which can help you see how much is being loaded and from where.

When dealing with more complicated preloaders, it can often be a good idea to separate the loading process from the preloader's visuals. In other words, when you create a graphical preloader, don't program the preloader to actually load anything. Instead, allow the preloader to accept a value from another source that is representative of what's being loaded. Doing this will allow you to easily change loading methods or preloader visuals with little hassle.

Example 2

preview

Here, a preloading script is set on the main timeline that finds what percent of the movie has loaded and passes that value to a preloader movie clip, preloader_mc, on the main timeline. That movie clip, by its own means, displays a visual representation of the amount loaded based on the value it was given from the preloader script. When the percent loaded has reached 1 (100%) the movie proceeds, just as with previous static example.

Code on main timeline getting percent of movie loaded

stop();
onEnterFrame = function(){
	var percent_loaded = _root.getBytesLoaded()/_root.getBytesTotal();
	preloader_mc.value = percent_loaded;
	if (percent_loaded == 1){
		delete onEnterFrame;
		play();
	}
}

Once preloading is complete, percent_loaded will equal 1, the onEnterFrame event handler will be cleared and the rest of the main movie will be played.

The example source file contains a number of different preloaders in its library, each which base their visuals on a value property representing the percent of loading, or more specifically, the percent of progress to represent visually (it doesn't even have to relate to preloading movies).

preloaders
Preloader examples

Any of these can be used as the movie's preloader graphics simply by using swap option in Flash making sure the preloader retains the name preloader_mc.

The default preloader used in this example is the bar loader--one of the more common types of preloaders and easy to make. All it mainly consists of is a movie clip in the shape of a bar (bar_mc) that, at normal size, represents 100% complete loading. That bar's _xscale is then scaled back to be based on the percent loaded, updated every frame with onEnterFrame. Notice that onEnterFrame is called as soon as its defined so that the preloader immediately updates as it appears.

var value = 0;

onEnterFrame = function(){
	bar_mc._xscale = 100 * value;
}

onEnterFrame();

Note: Advanced Preloaders

More information can be provided by preloader imagery or readouts if given not only the percent complete, but also bytes loaded and bytes total. For the sake of simplicity, examples here only use percent loaded (assigned to value). Examples of additional preloader information include:

var seconds_taken = getTimer()/1000;
var bytes_remaining = bytes_total - bytes_loaded;
var seconds_remaining = seconds_taken * bytes_total/bytes_loaded - seconds_taken;

Note that seconds_taken assumes the preloader starts when your movie starts. Otherwise you would need to note the value of getTimer when the preloading started and subtract that from the value of getTimer when finding seconds_taken.

Loading Complications

The logic behind preloaders really isn't that difficult to grasp. However, there are certain aspects about how Flash deals with movie content that causes preloaders to behave unexpectedly--specifically, and most famously, where flash starts loading at an already high preloader value (the #1 problem with Flash preloaders). The following explains why.

When Flash publishes a Flash movie to a swf file (which, by the way, stands for Small Web File) it optimizes the export so that no redundant objects in the source file's library are added to the resulting swf. This means that anything your Flash library that isn't used in the movie won't be included within any swf that movie creates. There is one small problem with this. What if you have a movie clip that you want to use in your swf that is not included on the movie's timeline--instead you want to create it dynamically with attachMovie? Flash has no way of determining which movie clips are to be used this way and can't determine that by ActionScript alone. This is why movie clip linkage properties and export for ActionScript exists.

symbol linkage
Linkage properties for a new movie clip symbol

Identifying a movie clip symbol to be exported for ActionScript instructs Flash that it would want to include this movie into a published swf regardless of whether or not it is on the timeline or not (and to allow attachMovie to attach it using its identifier). Once that has been set for a movie clip symbol, Flash is then able to create a swf and recognize that movie clip as one needing to be inluded despite it not existing on the timeline.

scan library
The process Flash uses to determine if a movie clip is added to a swf

Because Flash can't know when you might decide to actually use attachMovie to include any of the movie clips that are not on the timeline but exported for ActionScript, it assumes that it can be at any time, including the first script of the first frame. That being the case, Flash would need to preload those symbols before the first frame in your movie making sure that, if you actually did try to use attachMovie in the first frame, any symbols exported for ActionScript would be loaded and available for that frame. The same applies to ActionScript 2.0 classes. They too need to be included within the Flash movie before the actual first frame so that you are able to use them on that frame.

export prior to frame 1
ActionScript 2.0 classes and exported movie clips made available for frame 1

You can probably guess what this does for your preloader. If you have a lot of movie clips (or other library items like sounds, for example) all loading prior to frame 1 because of being exported for ActionScript, they will all load prior to your preloader. By the time the preloader itself loads and begins doing its job, there might not be much left to load. You're stuck with a preloader that starts much later than you'd expect it to because it had to wait for other content to load before it could even be loaded itself.

The export in first frame option was added (in Flash MX) to help fix this problem. By un-checking the export in first frame option you can prevent this pre-frame 1 loading from happening. Of course you are then left with the problem of Flash not knowing when to load your movie clips. In fact, if you uncheck export in the first frame for a symbol and that symbol does not exist somewhere on the timeline, it won't be included in the swf at all! So what do you do? Quite simply, include them on the timeline.

What you'll want to do is have a frame on your timeline that is used solely for the purpose of containing all content that would otherwise be exported in the first frame. This will allow Flash to include these items in the movie, but lets you decide where. And by where I mean after your preloader. A good place is usually on a frame directly after the preloader but before the movie starts. Then, when the preloader is complete, it can skip this frame and go directly to the start of the movie. This lets your preloader load before all of this extra baggage and prevents it from starting at 67%.

force inclusion
Preloader in frame 1, dynamic content in frame 2, and movie begins in frame 3

As mentioned before, ActionScript 2.0 classes are also included in a Flash movie prior to frame 1. The solution above, however, does not affect these classes, only movie clips or other items in your library. Though you might not think it at first, ActionScript 2.0 classes can make a difference, too. Version 2 components, for example, can add a lot of weight to your movie from their classes alone--all of which would load prior to frame 1 and would need to be loaded before your preloader gets a chance to. One V2 component alone may be enough to worry about (a single V2 Scrollbar is over 30K). Luckily, with Flash MX 2004 and later, you get a classes version of the export in first frame option available for movie clips. It's the export frame for classes option in your ActionScript 2.0 Publish settings.

export frame for classes
ActionScript 2.0 settings with export frame for classes setting

The export frame for classes option (File > Publish Settings > Flash tab > ActionScript version: (ActionScript 2.0) Settings button) lets you choose what frame you want all classes to be exported on. This goes an extra step beyond the export in first frame library option in that you get to specify a specific frame number and doesn't require that you add anything to the timeline manually. However, this option also affects all ActionScript 2.0 classes used in the entire movie. You cannot be selective about which classes are exported on what frames. This means that if your preloader uses an ActionScript 2.0 class, it would have to wait for all classes to load in order to work. Otherwise, you'll need a preloader that does not use an ActionScript 2.0 class (recommended).

There is another important side effect to using an export frame for classes other than frame 1. That is that component movie clips, or any movie clip associated with a class for that matter, must not be loaded prior to the ActionScript 2.0 class in which they are associated. That means if you change the export frame for classes, you have to make sure that your components and all movie clips associated with classes are not checked to export on frame 1 and that they are located on a frame in the timeline that is on or after the frame specified for the export frame for classes. If you do not do this, the movie clip will load without having access to the class it needs function and will not work properly or at all when used.

export movie clips with actionscript
All movie clips associated with classes should load on or after frame ActionScript it exported on

Note: Fixing Association With Object.registerClass

If a movie clip associated with a class loads before its class does, you can fix the association after the class has loaded using Object.registerClass. New instances of that class will then have the correct class association and function as intended.

Example 3

preview

This example is just like the previous example except at the end of the movie's animation, there is a TextArea component and an images movie clip that does not appear on the timeline but is attached dynamically using attachMovie. Each are exported for ActionScript in the linkage options available from the library. To make sure the preloader starts from the beginning and that these items are not preloaded for frame 1, exporting for the first frame was unchecked for each and they were placed on frame 2 of the main timeline - a frame skipped over once preloading is complete. In addition, in the publish settings, ActionScript 2.0 classes were set to export on frame 2. Because the export frame for classes is for frame 2, the TextArea component will be able to maintain its association with the class(es) it requires to function properly. If the export frame for classes was greater than 2, the TextArea component would not function because it would have loaded before its class.

The preloader script is like before, just now skipping over frame 2 where the TextArea and images movie clip sit.

stop();
onEnterFrame = function(){
	var percent_loaded = _root.getBytesLoaded()/_root.getBytesTotal();
	preloader_mc.value = percent_loaded;
	if (percent_loaded == 1){
		delete onEnterFrame;
		gotoAndPlay(3);
	}
}

Loading External Content

Often Flash movies will be divided up into multiple smaller movies with one main movie used to load content from other external movies. This allows the loading time for the main movie to be greatly reduced. The external movies, while capable of having their own internal preloaders, are usually loaded with a preloader loaded within the main movie. This not only supports greater modularity, but also reduces redundancy as your preloader would then not need to be reloaded for each time an external movie is loaded.

external movies
External swfs loaded into the main movie

There are various methods in Flash used to load external content depending on what that content is, audio, text, other swfs, etc. Here we'll focus on using loadMovie loading swfs and images into movie clips.

Note: Loading Other Types of Content

Though the focus on this tutorial is directred towards loading swfs and images, when dealing with other content like sound or text, there isn't really anything that changes other than the object from which getBytesLoaded and getBytesTotal are called. Like with MovieClip, the Sound, LoadVars, and XML classes each use getBytesLoaded and getBytesTotalthe same way.

One thing about loading external movies into a preexisting movie containing the preloader is that problems with library items loading in the first frame is nonexistent. Since the preloader is already loaded, it doesn't matter where Flash sticks things in the external movie. In fact, prior to Flash MX and the export in first frame option, often a base movie containing just a preloader was used to load in the main main movie from an external source to avoid comlications of items exported in the first frame.

Something you will have to worry about when preloading external content, though, is making sure you have valid return values for methods like getBytesLoaded and getBytesTotal. This is because your preloader, accessible prior to anything being loaded, can start functioning before Flash is able to access and correctly retrieve information about the file you're trying to load. This requires that before you try working with the values returned by getBytesLoaded and getBytesTotal you make sure that you are getting valid values. To validate your values, all you need is a simple if statement. This can be used with just getBytesTotal as it is pretty safe to assume that if a total has been correctly determined, so would a getBytesLoaded.

if (target.getBytesTotal() > 0) { ... } 

If getBytesTotal resolves to be an invalid number or -1 (which it may also return), the if condition will evaluate to false and additional preloader code can be avoided. Notice that a target reference is used here instead of _root. That's because some other movie clip, not the current main timeline, is being loaded here. Once valid values are received preloading can proceed normally.

Note: Movie Clip Byte Sizes

All movie clips, whether containing/loading external content or not, have a size in bytes that getBytesTotal will retrieve. For empty movie clips placed on the timeline, this is about 4 bytes. When using preloaders to load external content, you may find that if you start your preloader prior to using loadMovie, your preloader may complete prematurely since it will see that your target movie clip already has bytes loaded equal to bytes total. To prevent this, make sure you do not start your preloader until one frame after calling loadMovie. Setting an onEnterFrame event handler in the same script as loadMovie will allow for this since the onEnterFrame event isn't called until the beginning of the next frame.

There is a quirk involving Flash's first frame speedy-execution behavior. That is, the first frame in a Flash movie is a kind of "super frame" which executes script faster than the rate specified in the frame rate for the movie. This becomes a problem when you try to set an onEnterFrame event handler on frame 1 because it will be called almost immediately, which, when used with loadMovie will result in the target movie clip not being cleared of its original contents and thus making your preloader end before the content even began to load. It would be best to avoid loading this way directly on frame 1.

Don't forget that Flash loads content (namely swfs) into the player progressively, playing movies as they are loaded--starting even if the movie has not completely loaded. This can be a desirable effect. However, if you are using a preloader, chances are you will not want this to happen. After all, the whole point of a preloader is to make sure your content is loaded before going off and showing it to your viewers. That being the case, as with preloaders used for loading the main movie, you may find it necessary to use a stop() command to prevent the swf being loaded from playing. Additionally, you may want to also hide the content from view to assure that it isn't seen until loaded. This can be done using the _visible property or by inserting a blank frame on frame 1 of the movie being loaded. Though the _visible option may seem more appealing, consider the fact that other elements might be included in the first frame of whatever is being loaded--audio, for example. A stop command won't stop audio from playing; leaving frame 1 of the loaded movie blank and starting the audio until frame 2 will.

Note: Clearing Content

Don't forget that functions and properties assigned to a movie clip that loadMovie is used on are cleared from that movie clip when new content is loaded. If you have a movie clip which contains functions or properties you want to keep but still want to have loaded content, you would want to load that content into a child movie clip instead. Also, this behavior also prevents the onLoad event for movie clips from working because the onLoad event handler you assign to a movie clip would be cleared by the content being loaded before it could even be called.

Example 4

preview

This example uses 2 buttons to load external animations into an empty movie clip (container_mc) placed on the stage. Each, when pressed, calls a startPreload function which begins the loading process.

movie1_btn.onPress = function(){
	startPreload("load/tankoverhead.swf");
}

movie2_btn.onPress = function(){
	startPreload("load/tankturn.swf");
};

The startPreload function calls loadMovie to load the url passed. It also uses attachMovie to show the preloader for the loading of that movie (no longer does it just sit on the first frame - its now required to appear dynamically on demand), and sets an onEnterFrame event handler for managing that preloader.

function startPreload(url){
	container_mc.loadMovie(url);
	attachMovie("preloader anim", "preloader_mc", 500, {_x:275, _y:165});
	onEnterFrame = preloadContainer;
}

The onEnterFrame event handler is set to equal the preloadContainer function. This function checks for bytes loaded and total of the container movie clip and updates the preloader as needed making sure to check for a valid value from getBytesTotal. It also stops and hides the movie clip being loaded. It does this every frame just to be sure that it happens when first possible. When loading is complete, the loaded movie is played and revealed, the preloader movie clip is removed, and the onEnterFrame cleared.

function preloadContainer(){
	var bytes_loaded = container_mc.getBytesLoaded();
	var bytes_total = container_mc.getBytesTotal();
	
	container_mc.stop();
	container_mc._visible = false;
	
	if (bytes_total > 0){
		var percent_loaded = bytes_loaded/bytes_total;
		preloader_mc.value = percent_loaded;
			
		if (percent_loaded == 1){
			container_mc.play();
			container_mc._visible = true;
			
			preloader_mc.removeMovieClip();
			delete onEnterFrame;
		}
	}
}

The MovieClipLoader Class

Flash MX 2004 and Flash Player 7 introduced a new class, the MovieClipLoader class, to help with the processes of loading external movie clips. It pretty much replaces the need for a polling onEnterFrame to check for the progress of a clip. Instead, you use events from a MovieClipLoader instance that directly relate to the progress of content as it is loaded into Flash. As a result, problems associated with loading external movie clips is virtually nonexistent. A MovieClipLoader instance even has an onLoadError event that will inform you if an error has occurred during the loading process--something you can otherwise usually only guess on (e.g. by setting a timer to stop the preloader if no progress has been made within a certain amount of time).

Note: No MovieClipLoader for Main Movie

The MovieClipLoader class is for loading external movies into the current movie only. It cannot be used to load the main movie as it is loaded into the Flash player.

To use the MovieClipLoader class, you must first create an instance of the class. In following popular conventions, MovieClipLoader instances in ActionScript are followed by "_mcl".

var loader_mcl = new MovieClipLoader();

Once you have a MovieClipLoader instance, you can start defining event handlers for that instance that will react to the loading of content into a movie clip. These events are as follows

Event Description
MovieClipLoader.onLoadComplete Invoked when a file loaded with MovieClipLoader.loadClip() has completely downloaded.
MovieClipLoader.onLoadError Invoked when a file loaded with MovieClipLoader.loadClip() has failed to load.
MovieClipLoader.onLoadInit Invoked when the actions on the first frame of the loaded clip have been executed.
MovieClipLoader.onLoadProgress Invoked every time the loading content is written to disk during the loading process.
MovieClipLoader.onLoadStart Invoked when a call to MovieClipLoader.loadClip() has successfully begun to download a file.

The loadClip method is what replaces loadMovie loading a url into a target movie clip. Once called, events start firing and you're preloader can be on its way.

Note: onLoadInit

There is a little confusion about the onLoadInit event. The time at which this event is called is not exactly directly after the first frame of the loaded clip has been executed. Instead, it is called one frame after onLoadComplete--which really has nothing to do with the first frame at all. Granted, you're guaranteed the first frame would have been executed at that point in time, but it could also mean the first frame could have been executed 20 frames ago. This event basically represents just that guarantee that it has at least happened.

Note: MovieClipLoader in Flash MX 2004

You may find that MovieClipLoader events (namely onLoadComplete) do not fire when they should when using the simulate download setting for your movie testing in Flash MX 2004.

Example 5

preview

This example replicates the previous example except it uses a MovieClipLoader instance to load the animations. First a new MovieClipLoader instance is created and the current timeline is set to be a listener. This allows events to be defined in that timeline and work for that instance.

var loader_mcl = new MovieClipLoader();
loader_mcl.addListener(this);

The button events have remained the same but the startPreload function now simply calls loadClip.

function startPreload(url){
	loader_mcl.loadClip(url, container_mc);
}

The remaining code outlines the code used in the various events; when the loading starts, what happens when there's progress, when the loading is complete and what happens when there's an error.

function onLoadStart(target){
	attachMovie("preloader anim", "preloader_mc", 500, {_x:275, _y:165});
}

function onLoadProgress(target, bytes_loaded, bytes_total){
	target.stop();
	target._visible = false;
	preloader_mc.value = bytes_loaded/bytes_total;
}

function onLoadComplete(target){
	target.play();
	target._visible = true;
	preloader_mc.removeMovieClip();
}

function onLoadError(target, error_code){
	preloader_mc.removeMovieClip();
	trace(error_code);
}

Transitions With Preloaders

Transitions with preloaders aren't much different from other applications aside from the fact that within the transition, you have to make sure your content has been completely loaded (or loaded enough to warrant presenting the new content.

There are two basic kinds of transitions.

  1. Hide and reveal transitions and
  2. Blends

With hide and reveal transitions, you completely cover or hide your current content from view allowing an exchange of the new content to happen behind the scenes. When the content is revealed again, the old is replaced with the new. Blend transitions, on the other hand, are transitions that let you see both versions of the content and smoothly transitions from showing only the old content to showing only the new content (seeing both in some form or another during the transition process), usually through some kind of blend or dissolve--or something of the sort.

Hide and reveal transitions are the easiest. They let you reuse the same container movie clip to house all content, old and new. When new content is needed, it is simply loaded into the same movie clip in which the old content exists. It doesn't really matter what that movie clip looks like when this happens (dropping out etc.) since the transition would cover it up or the clip would in some way hidden as the transition took place. The loading process occurs while the content is hidden and the new content is revealed when completely loaded. The preloader just sits in the middle of the transition working when the content is not visible and instructing the transition to complete itself when loading is complete.

hide and reveal
A hide and reveal transition preloads during transition

Blend transitions are a little different. They don't work with the preloader as much since for blends to function, both versions of the content (new and old) need to be completely loaded (and in separate movie clips). The old content will remain visible until the new content is loaded with the preloader. When complete, the preloader then instructs the transition to play through in its entirety causing the old content to gradually disappear as new content gradually appears by whatever transition you decide to use.

blend
A blend transition preloads then transitions

Example 6

preview

Here a hide and reveal transition is used to load external images. The transition fills up the screen with a solid color and loads new content behind it revealing the stage again when loading is complete.

Buttons are similar to what have been seen, each calling a startPreloader to load a url. This time, though, startPreloader assigns a url and target property to the transition movie clip instructing the preloader within what is to be loaded. The transition movie clip (already present on the screen) is then told to play.

image1_btn.onPress = function(){
	startPreload("load/beach.jpg");
}

image2_btn.onPress = function(){
	startPreload("load/building.jpg");
}

function startPreload(url){
	preloader_mc.url = url;
	preloader_mc.target = content_mc;
	preloader_mc.gotoAndPlay(2);
}

The transition movie clip with the preloader is not attached dynamically in this example. Instead, it just sits on the screen on an empty frame until needed. This was simply done as a convenience. You could also use attachMovie to create it dynamically. Using the empty frame prevents the need of worrying about removing it, though.

The empty frame in frame 1 stops the transition and gives it a button null event handler to make it behave like a button. What this does is makes it so that buttons below the transition can continue to be active but cannot be clicked because the transition will intercept those actions, itself being a button. To make this as transparent as possible, the hand cursor is removed as well.

stop();
this.onPress = null;
this.useHandCursor = false;

The preloader script in middle of the transition is pretty standard with the only change being that loading is based off of the url and target properties assigned by startPreload.

stop();
this.target.loadMovie(this.url);
onEnterFrame = function(){
	var bytes_loaded = this.target.getBytesLoaded();
	var bytes_total = this.target.getBytesTotal();
	
	if (bytes_total > 0){
		var percent_loaded = bytes_loaded/bytes_total;
		preloader_mc.value = percent_loaded;
			
		if (percent_loaded == 1){
			delete onEnterFrame;
			play();
		}
	}
}

Example 7

preview

This example shows a blend transition fading between two loaded images. This example is a little more complicated as it involves 2 separate container movie clips for content to be loaded into as well as some arrangement swapping using swapDepths for those clips to let the new content load behind the old but fade in above it when completely loaded.

The two container movie clips themselves, container1_mc and container2_mc, each have another empty movie clip within them. This is the content_mc which is what new content is loaded into. This allows the actual container movie clips to have properties and functions associated with them that won't clear once new content is loaded. New content will always be loaded content movie clip of the bottom-most container movie clip. This is stored in the variable bottomcontainer. It starts off as container1_mc which was positioned below container2_mc to start.

var bottomcontainer = container1_mc; 

The buttons which load content are similar to before only they work off of the bottomcontainer reference instead of a specific movie clip. bottomcontainer could be container1_mc or container2_mc depending on which movie clip was used last time. Notice that _alpha is also set to 0 for the container and loadMovie is actually used on the contents_mc, not the container itself. This is because preloadContents is now being assigned to the container movie clip directly instead of using the onEnterFrame of the timeline. If loadMovie was used on that container clip, onEnterFrame would be removed when the content is loaded. Since onEnterFrame is being used for bottomcontainer, all future references to this will reference that movie clip.

image1_btn.onPress = function(){
	startPreload("load/beach.jpg");
}

image2_btn.onPress = function(){
	startPreload("load/building.jpg");
}

function startPreload(url){
	attachMovie("preloader anim", "preloader_mc", 500, {_x:275, _y:165});
	bottomcontainer._alpha = 0;
	bottomcontainer.contents_mc.loadMovie(url);
	bottomcontainer.onEnterFrame = preloadContents;
}

The preloadContents function is pretty typical just making sure that that correct target is used (contents_mc). The only other real difference is the call to this.onPreloaderComplete() when preloading is complete.

function preloadContents(){
	var bytes_loaded = this.contents_mc.getBytesLoaded();
	var bytes_total = this.contents_mc.getBytesTotal();
	
	if (bytes_total > 0){
		var percent_loaded = bytes_loaded/bytes_total;
		preloader_mc.value = percent_loaded;
			
		if (percent_loaded == 1){
			delete this.onEnterFrame;
			this.onPreloaderComplete();
		}
	}
}

The onPreloaderComplete function is assigned to each container movie clip and contains the actions that should occur once content has been loaded. Those actions are defined in the preloadComplete function

container1_mc.onPreloaderComplete = preloadComplete;
container2_mc.onPreloaderComplete = preloadComplete;

That function swaps the depths of the container clips so that the new content is placed above the old, reassigns bottomcontainer to the new bottom-most container, removes the preloader, and starts the transition fading process which is handled by fadeIn.

function preloadComplete(){
	container1_mc.swapDepths(container2_mc);
	
	if (container1_mc.getDepth() < container2_mc.getDepth()){
		bottomcontainer = container1_mc;
	}else{
		bottomcontainer = container2_mc;
	}
	
	preloader_mc.removeMovieClip();
	this.onEnterFrame = fadeIn;
}

All fadeIn does is fade in the movie clip, stopping itself when an _alpha of 100 is reached. This function could really handle any transition you like. This particular example just uses a simple fade.

function fadeIn(){
	if (this._alpha < 100){
		this._alpha += 5;
	}else{
		delete this.onEnterFrame;
	}
}

Conclusion

When working with preloaders, the main concern is usually that with elements of your movie loading prior to frame 1. This is the primary preloader crux. Once you get beyond issues revolving around the first frame, it's usually smooth sailing from then on out. Also, when loading external content, try to make use of the MovieClipLoader class when possible (i.e. when publishing for Flash 7 or greater). It can help you avoid additional complications as well.

The real problem is just knowing how Flash handles things. Once that is understood, everything else is pretty much trivial. Hopefully after having read this tutorial, you now have a better understanding of Flash and how to get preloaders to properly work when using it.