##### Tutorial Details
• Difficulty: Beginner
• Platform: Flash
• Language: AS3
• Software used: Flash Professional CS5
• Estimated Completion Time: (45 minutes)

In AS3 projects, you often need to load external assets like images and other SWFs. While loading these assets you have to keep track of several events for successful execution of your application. You might have been using some of these events like ProgressEvent, COMPLETE event. This tutorial shows you how to get info about the assets you’re loading with Loader.load(), using its associated events, all in one place. So if you’re having difficulty loading such assets, or you have less time in hand to debug, take a look at this.

(Preview image courtesy of VisualPharm.)

## Final Result Preview

Let’s take a look at the final result we will be working towards:

It won’t work embedded in this page (which shows you the responses in case of error) but it will work if you load the SWF directly.

## Step 1:The need to load assets

Hey, if you are in a hurry, you can skip this step. But, if you are relaxed, with a cup of coffee in hand, have a read.

In the early days when I started learning Flash 5 and AS1, I used to have all objects on the stage at once, and made them visible/invisible as required. Eventually as I started developing apps, I became more familiar with Flash’s system. Wow, now I was able to use “linkage identifier” to load objects from library. Getting more advanced, I soon realised the need for external assets. But unfortunately, there was no such powerful architecture. Meanwhile, Flash was going through drastic changes. Now “AS2″ was capable of loading external assets. Finally, when it lined up in Adobe’s family, the new event-based architecture “Action Script 3.0″ was introduced. In AS3, the need for loading external assets is much better addressed than in AS2.

So, when working with Flash we have three ways to manage our assets:

1. Put all required assets (MovieClips with instance names) on the stage and manipulate them as required.
2. Put all required assets in the Library and access them using “Identifier” in library panel.
3. Put all or some required assets outside Flash and load them dynamically.

The first method is not versatile. As the number of objects increases, the size of the SWF also increases (especially when there are lots of images). Imagine how much time it can take to load on user’s machine? Also, the performance of your application might degrade. But, still it can be handy enough for creating lightweight apps. (E.g. developing a simple game, in which player needs to find out key objects from the given image).

The second method is very much similar to the first one. Instead of having objects on the stage, now they are residing only in the library. Again, if there are lots of objects, then the issues with the SWF’s size and performance remain. But with this approach, you can easily create multiple instances of objects. Plus, the objects are much easier to handle than the first method. (E.g. games like “Tic Tac Toe”, “Tetris”, and “Snake” can be developed as they require fewer objects).

Note: The above “On Demand” method may not be suitable in case where assets are loaded and unloaded frequently (e.g. in an image viewer app).

Okay, so now we can conclude that, of the three methods, the third one is more flexible. But, as the system gets more advanced, it becomes more complicated to manage. Similarly, if you decide to go with third method, you will need to handle assets as one separate operation. You may call it “Asset Management” which can be divided into two parts:

• Handling assets manually (involves folder structures and operations like cut-copy-paste)

This tutorial covers the second part, so let’s look at that now.

As our program loads assets externally, it is now dependent on those assets. If any of our assets fail to load for some reason, then our entire application will be hampered. To avoid such failures, we really have to provide “Decision Making” power to our program.

Here’s one example. You have a coin-flipping game, where the coin is an externally loaded image. Now, if this image fails to load, then what next? This is the perfect point where your program will take some decision(s). It might load another image for the coin, stored as a proxy. It might load the stand-by coin if you have placed it in the Flash library. This can be a lightweight coin made up of vector graphics and strokes converted to fill to keep the size of the main SWF as small as possible. If you do not plan to have stand-by coin, then your program could warn the user about failure.

Of course, this was just one case. For a complete game, you will need to use a mature “Asset Management” system.

## Step 2: Which Type of Loader?

In an AS3 project, assets can be any of the following,

1. Images.
2. SWFs.
3. Sounds.
4. Videos.
5. Text files (including Text, XML, JSON, and sometimes Binary Data).

These assets have their own methods of loading as they are different in nature. You cannot see the sound, and you cannot hear images, so it is quite acceptable to have different techniques for these different types.

Hence, you cannot load sounds the way you load images and vice versa. You have to pick the right method for the selected assets.

1. Images and SWFs:load()” method of “Loader” class is used to load images and SWFs. Our tutorial is dedicated to this section.
2. Sounds:load()” method of “Sound” class is used to load external MP3 sound files.
3. Videos:

FLV video format or a video format that uses standard H.264 encoding is supported by AS3.

Video without FLV component can be loaded and streamed using classes like “NetConnection” and “NetStream“.

Video with FLV component can be loaded and streamed using “source” method as myFLVComponent.source("MyVideo.flv").

4. Text files (including Text, XML and sometimes Raw Binary Data):
5. To load such type of data, you have to use the URLLoader class, which loads data from the specified URL. Any type of data can be loaded but in the form of text or raw binary data or encoded variables.

e.g. You can also load an image in the form of raw binary data and further use it for processing with “ByteArray” class.

So, let us end the theoretical part here and move towards the practical stuff. Now we have enough knowledge about assets. In the rest of the tutorial, we will be dealing with the load() method (of “Loader” class) and its associated events, to monitor the loading process of an image and a SWF.

Before moving towards Loader class, first let us look at several events that are needed to monitor the loading operation:

• IOErrorEvent.IO_ERROR
• Our first task will be to check the availability of the specified target (i.e the “loadee”).

Sometimes, the target is not found due to incorrect file names or perhaps because the file itself no longer exists at the location. Even, in some cases, assets may not be readable. If everything is okay at this level, then we can jump to monitoring the loading process.

• Event.OPEN
• As soon as the loading is triggered, this event is dispatched. Here, we can initialize a preloader (e.g. set up the Progress indicator), before the PROGRESS event is dispatched. This OPEN event is the first thing to be dispatched in a (successful) loading operation.

This event depends on the loading environment. Meaning, if you are loading images remotely (say, over the Internet, rather than from the user’s hard drive) and if the connection is okay but the file is not found, even now this event will be dispatched. So, be careful if you are initializing a preloader here – or try to make your program very strict in handling an IO_Error event.

• ProgressEvent.PROGRESS
• We have got the target and now the loading is in progress. But we can’t just stay quiet and wait for the progress event to finish, because it takes some time to load the image (or SWF), especially when the image is heavy or being transferred online. So, to keep the user engaged, we must keep informing him about the state of the load. Now, what to inform?

While is in progress, we can display the message saying “Please wait. File is loading”. We can also display the “current bytes loaded” on the screen using information from the PROGRESS event.

We can do such tasks while this event is processing. Hence, it is at second position.

• Event.INIT

If you are loading SWF from local machine itself and the SWF is lightweight, then it is almost identically timed to the COMPLETE event. Many a time you will find no difference between INIT and COMPLETE events, because within no time, you are in a state of COMPLETE, immediately leaving INIT state.

But the situation changes when you are loading the SWF(s) from internet. In addition, if the SWF (having animations or lots of objects) is the target, then it will take more time to download. In this case the INIT becomes handy.

As soon as the SWF header is readable, this event is dispatched and the document class for the main SWF is instantiated. The first frame is available and you can do some preloading actions or you can define some properties while the rest of the part is still downloading.

This event is the third to fire in a successful load.

• HTTPStatusEvent.HTTP_STATUS
• When loading assets over the Internet (using an HTTP request), the HTTP status code (e.g. 200) is returned if the connection is OK. Otherwise, 0 is returned.

If the connection is okay, but the file is not found, then 404 is returned.

HTTP Status Messages

Although this event checks the status of the connection to the remote server, it is trigerred even in case of loading assets locally – but in this case it always returns 0. This event fires fourth.

• Event.COMPLETE
• As the name suggest, this event will be dispatched when an image (or SWF) is completely loaded on the user’s machine. At this point, the image or SWF is completely available for further process. Hence, this event is at last place in the loading operation.

There are also some other events like so:

• AsyncErrorEvent.ASYNC_ERROR:
• This error occurs when a SWF, running asynchronous code (like AS2), is loaded.

• SecurityErrorEvent.SECURITY_ERROR:
• This error occurs when Flash Player’s security model is violated during a loading process.

For the latest info on the security model of Flash Player, take a look at Flash Player Security.

For more info on SecurityErrorEvent.SECURITY_ERROR specifically, here are some links to follow:

Although we can skip some of these events – like “OPEN”, “HTTPStatus”, “INIT” – when loading assets locally, tracking all of them ensures a high level of monitoring a loading operation.

## Step 4: Preparing the Document Class

After knowing all necessary event types, now its time for loading assets.

First, we shall create a basic structure of our document class.

For detailed explanation about the document class check out this Quick Tip.

Also, there is “MyLoader_Complete.as” file, from the end of the tutorial. We are going to build this class, step by step, for better understanding. At the end of this tutorial, we will have our own version of this class.

Open Flash and create new “ActionScript 3.0 Class” file and name it “MyLoader”.

You will have the basic structure of the class like so:

package  {

// constructor code
}
}
}


So, first we must change the document class from “MyLoader_Complete” to “MyLoader”, in the Property Inspector of the FLA.

Now, the Class name must read like so:

The basic requirements can be listed down, like so:

• URLRequest Object to specify the path of an image.
• Display the image on the screen.

So, to fulfill above requirements, modify the “MyLoader.as” like so:

package  {

import flash.display.Sprite;
import flash.events.MouseEvent;

import flash.net.URLRequest;

public class MyLoader extends Sprite {

private var myURL:String;

myURL = "MyImage.png";

}

}
}
}


Since, the target was an image, we needed Loader Class to create Loader Object.

Hence, in our code we put the lines like so:

import flash.display.Loader;


Above line made the Loader class available to our program.

private var loader:Loader;


Above line declared the loader var to store Loader object.

loader = new Loader();


Above line created the Loader object and assigned it to a loader var.

Now, we can access load() method of Loader class.

In our code, we accessed load() method like so:

loader.load(new URLRequest(myURL));


The load() method is most crucial part of our code.

We passed only one parameter as URLRequest to this method. Actually it can take two parameters. The second parameter is LoaderContext object. The URLRequest is required while LoaderContext is optional parameter.

For example, loader.load( URLRequest, LoaderContext);

Let’s look at brief info about URLRequest and LoaderContext in next couple of steps.

## Step 6: URLRequest and Paths

In our code, we created the instance of URLRequest object like so:

loader.load(new URLRequest(myURL));  //myURL is a String


We used a shorthand method for creating an instance of URLRequest, which is okay for our example but not a good practice in general. It should not be used for big projects (e.g. a framework). The problem is that it leaves no reference to the URLRequest that we can use again later.

var urlRequest:URLRequest = new URLRequest();

urlRequest.url = myURL;

loader.load(urlRequest);

Now you can refer to urlRequest any time you want.

Now, let us learn about URLRequest, absolute paths, and relative paths.

URLRequest: This object gives us the ability to address the target by specifying a path.

This path can be one of two types:

1. Absolute Path – gives the full path to an asset.
2. Here are some examples of Absolute Path:

• http://SomeDomain/assets/MyImage.png
• D://MyProject/Assets/MyImage.png

Absolute Path is used mostly to download assets from other domains over the Internet. Being hard-coded, these paths do not give a flexible approach. Hence, for portable projects (especially for desktop apps) do not plan to use such paths.

It uses standard URI schemes like so:

• http
• https (Secure http)
• file

3. Relative Path – gives part of the path to the asset.
4. Relative Path can be divided into two parts like so:

• Document Relative
• MyImage.png (we used this path in the above code as myURL.)
• Assets/MyImage.png
• Root Relative
• ../Assets/MyImage.png
• ../../Assets/MyImage.png

Use case of above two paths depends on your project. But, in most cases you will end up using “Document Relative” path instead of “Root Relative” path.

Document Relative path is illustrated like so:

(The SWF is in a folder parallel to the Assets folder.)

Root Relative path is illustrated like so:

We did not used this parameter in our example, but having information about it will add the value.

• Security Domain
• Application Domain
• Check Policy file

Let us see some brief info about these properties.

• Security Domain

loaderContext.securityDomain = SecurityDomain.currentDomain;

This forces the loadee SWF (from other domain) to be placed into the loader SWF’s domain. By default the loadee SWF is placed in its own security domain (due to Flash Player’s security model).

Also, a policy file (e.g. crossdomain.xml) must be available on the loadee SWF’s server in order to established the trust between different servers. Thus, ensuring the interoperability between SWFs.

• Application Domain

Once, everything is in your own security domain, then you can specify loaderContext.applicationDomain.

e.g. loaderContext.applicationDomain = ApplicationDomain.currentDomain;

It allows cross scripting between SWFs. e.g. The loadee SWF can access the class associated with parent SWF, when set as ApplicationDomain.currentDomain.

ApplicationDomain.currentDomain.getDefinition("com.SomeFolder.SomeAS3Class");
ApplicationDomain.currentDomain.getDefinition("SomeLibrarySymbol") as Class;

(Note: Be updated with Adobe’s policy about accessing external scripts. It is related to security model. Adobe is constantly improving Security model. So keep track of Adobe’s documentation.)

Read the following links for more info on Application Domain:

Application Domain

• Check Policy file

This property can be used for both (SWF and an image).

e.g. loaderContext.checkPolicyFile = true;

When this property is set to true, then it always checks for policy file (crossdomain.xml) on server side. If it is not found, a security sandbox error is thrown.

Set this property to true only when you want to do more actions than just displaying that content on the screen. Otherwise keep this property as a false.

e.g. When you are loading an image from the secure server and if you want to use BitmapData.draw method on that loaded content, then set this property to true.

Following are some more links related to Flash Player Security:

Security sandboxes

Permission controls

Friends, in the above step we loaded an image without tracking the loading information. This time we will start monitoring the loading process of this image. For that we will make use of various events we discussed in Step 3.

But we still don’t know how to associate these events with Loader class. So, let us explore it.

The Loader class comes with a very important property: contentLoaderInfo.

This property is needed to associate the loading events with the load() method of Loader class.

The following is one example, which tracks the COMPLETE event of loading process.

loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete);

We are definitely going to use this property very soon. But, before that, let us see what exactly it does with Loader class.

The Loader class does not have any information about loading progress. In fact, this information is retrieved from the contentLoaderInfo which further utilizes the LoaderInfo object.

To understand these terms, we shall experiment with our “MyLoader.as” Class.

This time we shall actually use COMPLETE event. So, let us add our new function loadComplete and some more lines to the code like so:

import flash.events.Event;


The above line makes the Event class available to our program. Thus we can use COMPLETE event.

private function loadComplete(evt:Event):void
{
trace(evt.target);
}


This loadComplete function will be called when the target image is completely loaded. It will trace “Load Complete” to make sure that this function is invoked. It will also trace the type of the target (Loader).

Now, to associate this COMPLETE event with the Loader, we shall modify the constructor method in our code like so:

public function MyLoader() {

myURL = "MyImage.png";

}


The output window will show the results, like so:

Load Complete

[object LoaderInfo]

It returns LoaderInfo object as a target. So, we can say that, contentLoaderInfo utilizes the LoaderInfo object.

So, let us experiment more.

Modify the loadComplete method like so:

private function loadComplete(evt:Event):void
{
}


The output window will show the result like so:

contentLoaderInfo:600

loaderInfo:640

Here, contentLoaderInfo returned the height (600) of the target image.

And, loaderInfo returned the height (640) of the main (root) SWF.

If you want to experiment more, replace “height” property with “url”

This will make loaderInfo give the information about root SWF and contentLoaderInfo give the information about the content being loaded by the Loader object. But both utilize the LoaderInfo object.

OK, now we know how to associate the loading events using contentLoaderInfo with loader object. Next we shall start exploring all those events one by one in the proper sequence.

## Step 9: Which Events to Use?

We already have discussed the required events in Step 3. But, I am listing them again, just for a revision.

• IOErrorEvent.IO_ERROR
• Event.OPEN
• ProgressEvent.PROGRESS
• Event.INIT
• HTTPStatusEvent.HTTP_STATUS
• Event.COMPLETE

In the previous step, we used Event.COMPLETE. But remember, this is the last event to be fired, so we must track other events before Event.COMPLETE.

Also, while loading an image there is no need to track all the above events.

• IOErrorEvent.IO_ERROR
• ProgressEvent.PROGRESS
• Event.COMPLETE or Event.INIT

If image is loaded remotely (via HTTP request) add HTTPStatusEvent.HTTP_STATUS to the above list.

But, for our example, we shall track all above events for the sake of learning. Also, you can any time change the URL to load a SWF – because, most of the time, tracking the loading process of a SWF requires all these events.

So, let us start with IOErrorEvent.IO_ERROR.

## Step 10: IOErrorEvent.IO_ERROR

To track IOErrorEvent.IO_ERROR, first add an import statement like so:

import flash.events.IOErrorEvent;


We shall add a new method loadError like so:

private function loadError(evt:IOErrorEvent):void
{
}


In case the target image is not found, then IOErrorEvent will be triggered. The above loadError method will be invoked. This method will display a message about the URL in the dynamic textfield named “errorEventTF” which is inside the “monitor” MovieClip, already placed on the stage.

We shall also modify the constructor method to associate it with the loader object.

public function MyLoader() {

myURL = "MyImage.png";

}


To test the IOError status, put an incorrect url (e.g. myURL = "MyImage1.png").

Test the movie and click “Start Loading” button to see the status of IOError event. The monitor is displaying the incorrect URL.

## Step 11: Event.OPEN

To track Event.OPEN, we shall add a new method loadStart() like so:

private function loadStart(evt:Event):void
{
monitor.openEventTF.text = String("Path opened");
}


We shall also modify the constructor method to associate it with the loader object.

public function MyLoader() {

myURL = "MyImage.png";

}


Test the movie and click “Start Loading” button to see the status of OPEN event.

## Step 12: ProgressEvent.PROGRESS

We shall track loading progress of target image by updating the total number of bytes currently loaded.

To track ProgressEvent.PROGRESS event, first we shall add a new variable totBytesLoaded like so:

private var totBytesLoaded:Number;


Then, add import statement for ProgressEvent Class like so:

import flash.events.ProgressEvent;


Now, we shall add a new method loadProgress like so:

private function loadProgress(evt:ProgressEvent):void
{
}


We shall also modify the constructor method to associate it with the loader object.

public function MyLoader() {

myURL = "MyImage.png";

}


Test the movie and click “Start Loading” button to see the status of PROGRESS event.

You can still check the same local image, as if it is being loaded remotely. But, How?.

In Flash IDE test player, there is an option “Simulate Download”. This option must be checked to see how the download progress will look like for the same local image. This is just a simulation. It will give you only a rough idea about progress.

I have not added a progress bar, but if you wish to add it, then here are some lines to add a progress bar.

Before coding for progress bar, drag the ProgressBar component from the Component panel to the Library to make it available for us.

After that, add import statement for ProgressBar like so:

import fl.controls.ProgressBar;

Then, declare a var to hold progress bar like so:

var myProgressBar:ProgressBar;

Now, instantiate it and specify a source as contentLoaderInfo of a loader object like so:

myProgressBar = new ProgressBar();

myProgressBar.source = loader.contentLoaderInfo;

myProgressBar.x = stage.stageWidth/2 - myProgressBar.width/2;

myProgressBar.y = stage.stageHeight/2 - myProgressBar.height/2;

addChild(myProgressBar);

You can add these lines inside constructor method or you can create your own method and call it inside a constructor method.

Do not forget to remove this progress bar inside loadComplete method like so:

removeChild(myProgressBar);

## Step 13: Event.INIT

To track Event.INIT event, we shall add a new method initialised() like so:

private function initialised(evt:Event):void
{
monitor.initEventTF.text = String("Initialized");
}


We shall also modify the constructor method to associate it with loader object.

public function MyLoader() {

myURL = "MyImage.png";

}


Test the movie and click “Start Loading” button to see the status of INIT event.

## Step 14: HTTPStatusEvent.HTTP_STATUS

This HTTPStatusEvent is not required for loading images locally. We can simply replace the local path with a remote URL to check the status of this event.

For the sake of completeness, we shall associate this event, even for loading images locally (in which case it will return “0″ as a status code). Check Step 3 for more info on this event.

To associate HTTPStatusEvent, add the import statement like so:

import flash.events.HTTPStatusEvent;


Add a new line inside constructor method like so:

loader.contentLoaderInfo.addEventListener(HTTPStatusEvent.HTTP_STATUS, onHttpConnect);


Now, put the new function httpStatus like so:

private function httpStatus(evt:HTTPStatusEvent):void
{
monitor.httpEventTF.text = String(evt.status);
}


Test the movie and click on “Start Loading” button. The status will show “0″ since the target is local.

## Step 15: Event.COMPLETE

Finally, it’s time for Event.COMPLETE event. We already have added this COMPLETE event in Step 8, while learning LoaderInfo and contentLoaderInfo.

This is our destination. Treat this as an entry point for the code after loading is complete. Here you can start further processing.

Important tasks can be done here are listed down,

• Declare and/or assign values to required variables.
• Call for a function responsible for further processing.
• Add event listeners (e.g. ENTER_FRAME event).
• Remove event listeners.

Here, we shall modify the loadComplete() method by adding a line,

addChildAt(loader,0);

We already have added this line in a constructor method. But, instead of adding it in a constructor method, we must add it after the loading process is completed. This is a good practice.

So, we shall modify the constructor method, by removing the statement addChildAt(loader,0);

…to add the loaded image to the bottom of the display list.

The modified constructor will look like so:

public function MyLoader() {

myURL = "MyImage.png";

}


Now, modify loadComplete method like so:

private function loadComplete(evt:Event):void
{
}


Test the movie and click on “Start Loading” button to see the status of COMPLETE event.

Thus, we have the complete setup for monitoring the loading process of an image as well as SWF.

Also, you can simply replace the address path to load an image or SWF from any accessible remote server.

Now, we shall see how to load an image from internet. Of course you must have a working Internet connection.

First, we shall change our myURL like so:

myURL = "http://www.free-pictures-photos.com/architecture/house-5xl3.jpg";


Since, being “Test Player”, it allowed to load the target image over internet. But, if you run “SWF” outside Flash IDE, the Flash Player Security dialog box will tell you to go to Settings.

To prevent from this warning, we have two ways around it:

1. Set “Access network only” for Local playback security under Publish Settings.

2. If you want to keep “Access local files only” for Local playback security under Publish Settings and still want to load a target from internet, then, you need to register that SWF as “Trusted” file. To make it “Trusted“, run SWF outside Flash. Right click inside player and click on Global Settings from the context menu.

Then go to the “Advanced” tab and click “Trusted Location Settings”.

Now, under “Add Site”, click “Add File” and browse for this same SWF (i.e LoaderClassExample.swf). After specifying the path for this SWF, click on “Confirm” button.

If suitable, you can also create “Projector.exe” to avoid all above settings. Projectors are always registered as trusted files.

## So Why Doesn’t the Example Load?

Editor’s note:

You may be wondering why the example SWF (at the top of the page) doesn’t load the image when embedded in the page, but does load it when loaded in the browser directly.

This is because we host our SWFs and images on a different domain to the tutorial; they’re on s3.com rather than tutsplus.com. When the SWF tries to load the image, it’s looking for it at http://active.tutsplus.com/tutorials/actionscript/MyImage.png, because it’s using a relative path to this page.

However, the image is actually somewhere on s3.com, which means the SWF can’t find it. To get around this, we can use the SWF’s own loaderInfo.url property to find the URL of the actual SWF, and use this to construct a path to the image.

(Alternatively, we could hard-code in an absolute path to the image, but that’s pretty inflexible.)

For more info, take a look at Step 21 onwards of this tutorial.

## Conclusion:

Friends, that’s it for now. In this tutorial we saw how to load assets (in our case, an image) and monitored the loading process. We saw various events along with contentLoaderInfo, loaderInfo, absolute/relative paths and LoaderContext. We also experimented with loading an image from internet.

• Ivan

Good Stuff :)

• Louis

Nice!

I remember I had a problem when swf and container html were in different folders and I had to load several jpegs and an flv. The flv path should be realtive to the html while the other paths should be relative to the swf. Sounds familiar and if so, any remarks?

• http://michaeljameswilliams.com/ Michael James Williams

Hey Louis, check the very last section of the tut :) I’ve added a note explaining what you can do.