Chapter 13. Loading Assets

IN THIS CHAPTER

Loading SWFs and Images

Loading Data

Communicating with Loaded SWFs

Additional Online Resources

What’s Next?

You don’t always need to load external assets at runtime, but the ability to do so is extremely important. Loading assets on the fly reduces initial file size and, therefore, load times. It also increases the degree to which a Flash experience can change—not only through the all-important dynamic nature of runtime content updates, but also by streamlining the editing process. For example, you can alter external assets easier and faster than you can republish an FLA file every time an update occurs.

Augmenting prior discussions regarding sound, video, and plain text, this chapter will teach you how to load external SWFs and images. You’ll also take a peek at loading variables and binary data, and see how to increase your error checking efforts. Specifically, we’ll look at:

  • Loading SWFs and Images. Right out of the gate, it’s fairly easy to load SWFs and JPG, PNG, and GIF images. Third-party ActionScript libraries support loading even more asset types. We’ll look at simple syntax examples and then build a multipurpose class that can handle some error checking and reporting for you automatically.

  • Loading Data. Next we’ll discuss loading text, URL variables, and binary data. We discussed loading text from external sources in Chapter 10 but limited our coverage to loading HTML and CSS information. In this chapter, we’ll expand the scope of our discussion to loading URL-encoded variables and binary data. We’ll also write a multipurpose class you can use to load data. In Chapter 14 you’ll use that class to load XML.

  • Communicating with Loaded SWFs. After a SWF is loaded, the parent and child SWFs can communicate. We’ll discuss communication in both directions, and demonstrate a variety of tasks you may want to perform in the process.

  • Additional Online Resources. We’ll wrap up the chapter by referencing two additional loading-related topics discussed online. First we’ll describe problems caused by loading SWFs that use Text Layout Framework (TLF) assets (featured in Chapter 10). TLF assets use a custom preloader at runtime, which presents its own unique difficulties. We’ll point to two solutions, including Adobe’s new SafeLoader class, designed to successfully load SWFs that use TLF. Finally, we’ll introduce a great new ActionScript 3.0 loading library called LoaderMax, created by GreenSock, the makers of TweenLite.

Loading SWFs and Images

There are a few ways to load SWFs or images at runtime, but you’ll commonly use the Loader class in one way or another. To simplify the process of loading these visual assets, the Loader is also a display object. This makes it much easier to load and display visual assets because the Loader itself can be added to the display list, rather than waiting for its content to finish loading. In addition, because it’s a display object, you can use a variety of properties and methods shared with other display objects, affecting position (x, y), transformation (alpha, rotation), event management (addEventListener()) and more.

Loading SWFs

The following example is found in the load_swf.fla source file. Line 1 creates an instance of the Loader class, line 2 loads a SWF using a URLRequest instance, and line 3 adds the Loader instance to the display list. Even if it takes some time for the remote SWF to load, the Loader is already waiting, a little bit like a TV waiting for a program to begin.

1    var swfLoader:Loader = new Loader();
2    swfLoader.load(new URLRequest("swfToLoad.swf"));
3    addChild(swfLoader);

One important difference between the Loader class and other display object classes, such as MovieClip, is that event listeners are usually attached to the contentLoaderInfo property of the Loader instance, rather than the instance itself. The property references an instance of the LoaderInfo class, which traffics all information about the content of the Loader.

For example, if you attached an event listener to the Loader instance that listened for the COMPLETE event, it would work without error, but would respond to the fact that the Loader itself had loaded, not its content. As this is virtually instantaneous and doesn’t relate to the content you’re trying to load, it’s not very helpful. If you attached the same listener to the contentLoaderInfo property of the Loader instead, it would trigger its function when the content finished loading.

The following code, added to the prior example, stresses two concepts. First, it demonstrates attaching an event listener to the contentLoaderInfo property, as discussed (lines 5 through 7), showing that the target of the listener is the LoaderInfo instance described (line 10). Second, it shows that you can access the Loader instance from the data sent with the event, as well as the content of the Loader, as seen in lines 11 and 12, respectively. Note, too, that the example cleans up after itself by removing the COMPLETE event listener in line 9, once the loading is finished.

4    //use contentLoaderInfo for listeners
5    swfLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,
6                                                 onComplete,
7                                                 false, 0, true);
8    function onComplete(evt:Event):void {
9        evt.target.removeEventListener(Event.COMPLETE, onComplete);
10        trace(evt.target);
11        trace(evt.target.loader);
12        trace(evt.target.loader.content);
13    }

Loading Images

Waiting for the content of the Loader to finish loading is important when you need to work with the content rather than just display it. For example, we discussed working with bitmaps in Chapter 9, both with and without adding them to the display list. For example, if you just want to load the bitmap data from the bitmap, you don’t need to add it to the display list. In this case, you can’t pull bitmap data from a Loader instance and, even if you do want to add the Loader content to the display list, you can’t add something that hasn’t yet loaded.

The following example, found in the load_jpg.fla source file, uses the same basic syntax as the previous example, but with two significant differences. First, it loads a JPG rather than a SWF. Second, it adds the JPG directly to the display list (line 9) instead of adding the Loader instance. The result is a single child in the display list that is of type Bitmap. As a demonstration of using Loader properties, it also traces the bytesLoaded and bytesTotal of the loaded asset in lines 11 and 12. (After loading is complete, both numbers should be the same, no matter what the asset’s size.)

1    var jpgLoader:Loader = new Loader();
2    jpgLoader.load(new URLRequest("imageToLoad.jpg"));
3
4    jpgLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,
5                                                 onComplete,
6                                                 false, 0, true);
7    function onComplete(evt:Event):void {
8        evt.target.removeEventListener(Event.COMPLETE, onComplete);
9        addChild(evt.target.content);
10
11        trace(evt.target.bytesLoaded);
12        trace(evt.target.bytesTotal);
13    }

Writing a Multiuse SWF and Image Loading Class

image with no caption

The previous examples presented the simplest syntax for loading visual assets. Typical loading tasks are more involved, because they include additional features such as error checking and tracking loading progress.

Unfortunately, this can result in long scripts and become tedious quickly. So we’ll write a multipurpose class that will not only load SWF and image files, but will also report errors, monitor loading progress, and provide other diagnostic options, if you desire. The class will also mimic some of the features of the Loader class, allowing you to use much of the same syntax you would use if writing the code from scratch each time using that class. This is helpful because one of the drawbacks of a do-it-all approach like this is less flexibility. If the new class resembles the existing Loader class in useful ways, you can use the new class instead when you want a diagnostic environment rolled into a simple load, but revert to Loader when you want more control.

Note

You can even type the new class as Loader when creating instances, so your code can be more flexible.

Writing the CustomLoader Class

The class we want to write is called CustomLoader and is in the in the loading directory of the learningactionscript3 package we’ve been developing throughout the book. We’ll be using this class with the load_swf_custom.fla and load_jpg_custom.fla source files, if you want to test it before proceeding.

Lines 1 through 9 declare the package and import all required classes. We’ll discuss classes from the flash.events package that we haven’t mentioned before.

Line 11 declares the class and extends the Loader class. This makes the accessible properties, methods, and events of the Loader class available to our custom loader through inheritance. Lines 13 through 16 declare four private properties that will contain: a reference to the LoaderInfo instance of the class inherited from Loader (line 13), the path to the asset you want to load (line 14), a flag used to enable and disable trace statements (line 15), and a number between 0 and 1 representing the percentage of the asset’s bytes that have already been loaded (line 16).

Note

See Chapter 6 for more information about inheritance.

1    package com.learningactionscript3.loading {
2
3        import flash.display.Loader;
4        import flash.display.LoaderInfo;
5        import flash.events.Event;
6        import flash.events.HTTPStatusEvent;
7        import flash.events.IOErrorEvent;
8        import flash.events.ProgressEvent;
9        import flash.net.URLRequest;
10
11        public class CustomLoader extends Loader {
12
13            private var _ldrInfo:LoaderInfo;
14            private var _path:String;
15            private var _verbose:Boolean = false;
16            private var _loadedPercent:Number = 0;

The constructor is pretty simple. It takes two arguments: the asset path and flag to show trace output, as mentioned previously, both with default values. Lines 20 and 21 populate class properties with data provided to the constructor during instantiation. Line 23 calls the addListeners() method, which adds all the listeners used internally by the class (more on this in a moment).

The last lines of the constructor (25 through 31) load the requested asset if a path is passed into the constructor during instantiation. Providing a default value for path, and checking path before calling the load() method, means that you can load assets in two ways. First, you can pass a simple string to the constructor during instantiation. In this case, path will contain a String, and load() will be called in the constructor. Or, you can pass nothing to the class during instantiation (in which case path will remain null, and load() will not be called in the constructor) and use the load() method from the class instance with a URLRequest, just as you do with the Loader class. We’ll demonstrate both techniques when we show usage examples.

Before we talk about the try..catch block that surrounds the load() method, note that no Loader instance is created before loading. This is because the class you’re writing extends the Loader class and, through inheritance, we can use its accessible methods, which include load(). Therefore, the this keyword is used instead, so the class loads the asset without having to create an additional Loader.

A try..catch block, discussed at the end of Chapter 2, allows you to try something but suppress a resulting error to prevent it from being seen by those viewing your SWF in the wild. You can use a try..catch block in many ways. For example, you could try to load an asset from a remote server and, upon receiving an error, load a local version of the asset instead. More generically, you can use a try..catch block when a runtime error is possible so the error doesn’t reach the user. It’s helpful to trace these errors and add descriptive messages, so it’s easier to track them down during development.

17    //constructor
18    public function CustomLoader(path:String=null,
19                                 verbose:Boolean=false) {
20        _path = path;
21        _verbose = verbose;
22
23        addListeners();
24
25        if (path != null) {
26            try {
27                this.load(new URLRequest(path));
28            } catch (err:Error) {
29                trace("Cannot load", _path, err.message);
30            }
31        }
32    }

The addListeners() and removeListeners() methods do nothing but add and remove listeners, respectively, but there are a few things worthy of note.

First, in line 35 the listeners are added to the contentLoaderInfo property of the class (again, inherited from Loader), as explained in the Loading SWFs section of this chapter.

Second, we’re adding several new events, including some that come from event classes we haven’t previously discussed. For completeness, let’s briefly go over when each event is dispatched.

  • Event.OPEN: When the loading process is initiated. If this event is never received, you know loading never even started.

  • ProgressEvent.PROGRESS: Each time data is received during the load. This allows you to update a loading progress bar.

  • HTTPStatusEvent.HTTP_STATUS: When an HTTP request is made (such as fetching an asset from a server) and a status code is detected. For more information see http://en.wikipedia.org/wiki/List_of_HTTP_status_codes.

  • Event.INIT: When enough of the loading process is complete to have access to the properties of the object. If, for example, you try to query the width of a loaded asset before this event is dispatched, it will likely be 0. After properties are accessible, the correct width will be available.

  • Event.COMPLETE: When loading is finished. This occurs after Event.INIT.

  • IOErrorEvent.IO_ERROR: When an input/output error occurs. One example of such an error is when the asset can’t be found at the URL provided.

  • Event.UNLOAD: When the asset is unloaded. This is usually the last event to be dispatched.

    Note

    New to Flash Player version 10.1 is the uncaughtErrorEvents property of the Loader and LoaderInfo classes. This allows you to trap any errors not caught by other means (such as a try..catch block) in your code. For more information, see the “Trapping Uncaught Errors” post at the companion website, http://www.LearningActionScript3.com.

Lastly, notice that the removeListeners() method is public. This allows you to remove all listeners from outside the class, when you’re through using the class instance you created. In some cases, you want to remove listeners right away, such as when you only need your listener once, as demonstrated in the examples earlier in this chapter. In other circumstances, you may want to use the same Loader instance repeatedly to load asset after asset, in which case you want the listeners to remain active. The removeListeners() method allows you to remove the listeners any time you like.

Note

Another way to maintain your listeners is to add them before every load and remove them every time the load is complete. To keep your class as self-reliant as possible, you want to add the listeners when calling the load() method. This requires that you override the load() method, as discussed in the Polymorphism section of Chapter 6. The post, “Overriding the load() Method in Custom Loader Classes,” found at the companion website shows how this is done.

33    //listeners
34    private function addListeners():void {
35        _ldrInfo = this.contentLoaderInfo;
36        _ldrInfo.addEventListener(Event.OPEN,
37                                  onOpen, false, 0, true);
38        _ldrInfo.addEventListener(ProgressEvent.PROGRESS,
39                                  onProgress, false, 0, true);
40        _ldrInfo.addEventListener(HTTPStatusEvent.HTTP_STATUS,
41                                  onStatusEvent,
42                                  false, 0, true);
43        _ldrInfo.addEventListener(Event.INIT,
44                                  onInit, false, 0, true);
45        _ldrInfo.addEventListener(Event.COMPLETE,
46                                  onComplete, false, 0, true);
47        _ldrInfo.addEventListener(IOErrorEvent.IO_ERROR,
48                                  onIOError, false, 0, true);
49        _ldrInfo.addEventListener(Event.UNLOAD,
50                                  onUnloadContent,
51                                  false, 0, true);
52    }
53
54    public function removeListeners():void {
55        _ldrInfo.removeEventListener(Event.OPEN, onOpen);
56        _ldrInfo.removeEventListener(ProgressEvent.PROGRESS,
57                                  onProgress);
58        _ldrInfo.removeEventListener(HTTPStatusEvent.HTTP_STATUS,
59                                  onStatusEvent);
60        _ldrInfo.removeEventListener(Event.INIT, onInit);
61        _ldrInfo.removeEventListener(Event.COMPLETE,
62                                  onComplete);
63        _ldrInfo.removeEventListener(IOErrorEvent.IO_ERROR,
64                                  onIOError);
65        _ldrInfo.removeEventListener(Event.UNLOAD,
66                                  onUnloadContent);
67    }

The remainder of the class contains the listener methods, one getter, and one setter. The listener methods all trace specific feedback during the loading process, only if you pass true into the verbose flag during instantiation. Note, however, that the trace in the onIOError() method is not wrapped in a conditional that uses the _verbose Boolean. This is because we only want to turn on and off the logging feature, not any valid error reports. If the error were included in the list of items shown only when _verbose is true, we would have to see all diagnostic text all the time just to see any input/output errors.

The onProgress() method also calculates the percent that an asset has loaded. This way, if you want to create a progress bar, you can simply check the related property, percentLoaded, via the getter at the end of the class, instead of calculating the value yourself. The onInit() method also traces a few properties of the asset to help you in your loading diagnostics. The first is the asset’s URL (line 89) and, if the asset is a SWF, lines 93 through 96 trace the version of the Flash Player and ActionScript that the SWF was compiled for, and the SWF’s frame rate.

The percentLoaded getter provides access to the _loadedPercent property previously described, and the verbose setter allows you to optionally turn on or off debugging through a property, rather than in the constructor.

Note

In this class, enabling debugging through the constructor parameter or the verbose setter is entirely a matter of preference. The setter was provided to allow the instantiation of the class to more closely resemble the instantiation of the Loader class.

68            //listener methods, getter, and setter
69            private function onOpen(evt:Event):void {
70                if (_verbose) { trace("Loading begun:", _path); }
71            }
72
73            private function onProgress(evt:ProgressEvent):void {
74                _loadedPercent = evt.bytesLoaded / evt.bytesTotal;
75
76                if (_verbose) {
77                    trace("Loading", _path,
78                        "-- progress (0-1):", _loadedPercent);
79                }
80            }
81
82            private function onStatusEvent(evt:HTTPStatusEvent):void {
83                if (_verbose) { trace("HTTP status:", evt.status); }
84            }
85
86            private function onInit(evt:Event):void {
87                if (_verbose) {
88                    trace("Content initialized. Properties:");
89                    trace("url:", evt.target.url);
90                    trace("Same Domain:", evt.target.sameDomain);
91                    if (evt.target.contentType ==
92                        "application/x-shockwave-flash") {
93                        trace("SWF Version:", evt.target.swfVersion);
94                        trace("AS Version:",
95                            evt.target.actionScriptVersion);
96                        trace("Frame Rate:", evt.target.frameRate);
97                    }
98                }
99            }
100
101            private function onComplete(evt:Event):void {
102                if (_verbose) { trace("Loading complete:", _path); }
103            }
104
105            private function onUnloadContent(evt:Event):void {
106                if (_verbose) { trace("Unloaded:", _path); }
107            }
108
109            private function onIOError(evt:IOErrorEvent):void {
110                trace("CustomLoader loading error:
", evt.text);
111            }
112
113            public function get percentLoaded():Number {
114                return _loadedPercent;
115            }
116
117            public function set verbose(bool:Boolean):void {
118                _verbose = bool;
119            }
120        }
121    }

Using the CustomLoader Class

Because we extended the Loader class when writing CustomLoader, both classes use similar syntax. The following examples replicate the previous examples closely to demonstrate this benefit of inheritance.

Loading SWFs

The first example, found in the load_swf_custom.fla, loads a SWF. After importing the class in line 1, line 3 passes the SWF’s path to the constructor during instantiation, and the class takes care of the URLRequest and call to the load() method. The only other difference between this script and the example shown in the Loading SWFs section is in line 11. Because the example makes no further use of the CustomLoader class, all its listeners are removed.

1    import com.learningactionscript3.loading.CustomLoader;
2
3    var swfLoader:CustomLoader = new CustomLoader("swfToLoad.swf", true);
4    addChild(swfLoader);
5
6    swfLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,
7                                                 onComplete,
8                                                 false, 0, true);
9    function onComplete(evt:Event):void {
10        evt.target.removeEventListener(Event.COMPLETE, onComplete);
11        evt.target.loader.removeListeners();
12        trace(evt.target);
13        trace(evt.target.content);
14        trace(evt.target.loader);
15    }

Note

The event listeners in the example FLA files are not the same as the event listeners inside the class. All the internal listeners are at the class level, and are private so nothing outside the class is aware of their existence. The listeners in the example FLA files are applied to class instances.

Loading images

The second example, found in the load_jpg_custom.fla, uses CustomLoader much the same way Loader is used. The instantiation process in line 3 passes no values to the constructor, the verbose flag is enabled in line 4, and loading is accomplished via the load() method and a URLRequest instance in line 5. Like the previous JPG loading example, this script also loads the JPG directly to the display list in the last instruction of the onComplete() method.

This example also adds the use of the percentLoaded getter to increase the horizontal scale of a progress bar. In line 7 the progress bar is created using the createProgressBar() function found at the end of the script. The function creates a sprite, draws a green rectangle, and returns the sprite to the progressBar variable. The sprite is then added to the display list in line 8.

Two listeners are then added to the contentLoaderInfo property of the CustomLoader instance, so the property is stored in a variable for efficiency. In addition to the COMPLETE event listener found in the prior JPG loading example, a PROGRESS event listener is added in lines 13 through 15. It calls the onProgress() function in lines 17 through 19, which updates the scaleX property of the progress bar sprite every time asset data is received during the loading process.

1    import com.learningactionscript3.loading.CustomLoader;
2
3    var jpgLoader:CustomLoader = new CustomLoader();
4    jpgLoader.verbose = true;
5    jpgLoader.load(new URLRequest("imageToLoad.jpg"));
6
7    var progressBar:Sprite = createProgressBar();
8    addChild(progressBar);
9
10    var jpgLoaderInfo:LoaderInfo = jpgLoader.contentLoaderInfo;
11    jpgLoaderInfo.addEventListener(Event.COMPLETE, onComplete,
12                                   false, 0, true);
13    jpgLoaderInfo.addEventListener(ProgressEvent.PROGRESS,
14                                   onProgress,
15                                   false, 0, true);
16
17    function onProgress(evt:Event):void {
18        progressBar.scaleX = evt.target.loader.percentLoaded;
19    }
20
21    function onComplete(evt:Event):void {
22        evt.target.removeEventListener(Event.COMPLETE, onComplete);
23        evt.target.loader.removeListeners();
24        addChild(evt.target.content);
25    }
26
27    function createProgressBar():Sprite {
28        var sp:Sprite = new Sprite();
29        var g:Graphics = sp.graphics;
30        g.beginFill(0x00FF00);
31        g.drawRect(0, 0, 100, 10);
32        g.endFill();
33        sp.x = sp.y = 10;
34        return sp;
35    }

Note

If you want your usage of the Loader and CustomLoader classes to be as similar as possible, so you can switch between them with as few edits as possible, you can still enable verbose tracing without loading the asset immediately. You can set up your code like the custom JPG loading example, so the load() method is used separately—just like using the Loader class. However, when instantiating CustomLoader (line 3 in the example), just pass in null and true as the parameter values:

new CustomLoader(null, true);

This will enable verbose logging, but will not invoke the load() method in the class constructor.

Loading Data

While the Loader class will load visual assets, data such as text, URL variables, and even binary data, is loaded with the URLLoader class. Using the URLLoader class is similar in many ways to using the Loader class. In fact, we’ll write a custom class for loading data that will closely resemble the programming design and syntax of the CustomLoader class we wrote previously.

Just like the Loader class can load more than one kind of object (SWF and image), URLLoader can load three kinds of data, selected with the dataFormat property of the URLLoader instance. Plain text (such as text, HTML, CSS and so on) returns a string. URL-encoded variables (such as HTML form data and server responses) returns an instance of the URLVariables class with a collection of variables and corresponding values. Binary data (such as image or sound data) returns a ByteArray.

We introduced loading plain text in the Loading HTML and CSS section of Chapter 10, but we’ll cover it again here for completeness. We’ll also include examples of loading variables and binary data, including a beyond the basics look at how you can use binary data.

Note

Loading XML is just like loading text. We’ll cover loading XML in detail in Chapter 14 and make use of the CustomURLLoader class you’ll write in this chapter.

Loading Text

The default behavior of the URLLoader class is to load text. The following example, found in the load_text.fla source file, is the simplest implementation of the URLLoader class. All you need to do is instantiate the class (line 1), and load the text file using a URLRequest instance. This example uses a COMPLETE event listener to initialize a text field when the loading is finished (lines 4 through 15), populate the field with the text data sent with the event (line 13), and add the field to the display list (line 14).

1    var ldrText:URLLoader = new URLLoader();
2    ldrText.load(new URLRequest("lorem.txt"));
3
4    ldrText.addEventListener(Event.COMPLETE, onComplete,
5                             false, 0, true);
6    function onComplete(evt:Event):void {
7        evt.target.removeEventListener(Event.COMPLETE, onComplete);
8        var txtFld:TextField = new TextField();
9        txtFld.x = txtFld.y = 20;
10        txtFld.width = 500;
11        txtFld.height = 350;
12        txtFld.multiline = txtFld.wordWrap = true;
13        txtFld.text = evt.target.data;
14        addChild(txtFld);
15    }

Loading Variables

One of the ways to send data between client and server is by using name-value pairs (also called attribute-value pairs). These are assembled in a URL like those sent from an HTML form or returned from some web applications like search tools. An example is firstname=Liz&lastname=Lemon.

If your project requires communication using URL variables, you must set the dataFormat property of the URLLoader class to URLLoaderDataFormat.VARIABLES before loading. This automatically changes the data returned from the loading process to a URLVariables object. Names and values are created in the object to match the names and values from the loading result. You can then access those properties to retrieve their values.

Web-based applications change frequently, so we’ve demonstrated this syntax using a local file written as URL variables. (Local URLs are no different to URLLoader than remote server URLs.) The file vars.txt contains the following data:

name=Joe&age=25

This data will be loaded by the following example, found in load_vars.fla. The example assigns the dataFormat property in line 2, and the property values are traced from the event target’s data property in lines 9 and 10.

1    var ldrVars:URLLoader = new URLLoader();
2    ldrVars.dataFormat = URLLoaderDataFormat.VARIABLES;
3    ldrVars.load(new URLRequest("vars.txt"));
4
5    ldrVars.addEventListener(Event.COMPLETE, onComplete,
6                             false, 0, true);
7    function onComplete(evt:Event):void {
8        evt.target.removeEventListener(Event.COMPLETE, onComplete);
9        trace("name property:", evt.target.data.name);
10        trace("age property:", evt.target.data.age);
11    }

The following is the trace output:

//name property: Joe
//age property: 25

Loading Binary Data

It’s also possible to load binary data from a URL, which is stored in a ByteArray. In this book, we’ve already used the ByteArray to load frequency spectrum data from sounds at runtime. ActionScript 3.0 has also been used to create FTP clients, VNC clients, and image loaders, just to name a few examples.

To send or load binary data with the URLLoader class, you must set the dataFormat property to URLLoaderDataFormat.BINARY. The following example, found in the load_binary.fla source file, sets the property in line 2, loads an image in line 3, and, upon completing the load, creates a Loader instance to read the bytes of data returned from the URLLoader instance, and adds the instance to the display list (lines 9 through 11).

1    var imgLoader:URLLoader = new URLLoader();
2    imgLoader.dataFormat = URLLoaderDataFormat.BINARY;
3    imgLoader.load(new URLRequest("imageToLoad.jpg"));
4
5    imgLoader.addEventListener(Event.COMPLETE, onComplete,
6                               false, 0, true);
7    function onComplete(evt:Event):void {
8        evt.target.removeEventListener(Event.COMPLETE, onComplete);
9        var ldr:Loader = new Loader();
10        ldr.loadBytes(evt.target.data);
11        addChild(ldr);
12    }

This example was designed to be simple to introduce the syntax for loading binary data. Later in the chapter, a beyond-the-basics example will use this technique to load a Pixel Bender filter to process an image.

Note

Pixel Bender is an Adobe technology that lets you use a programming language based on C to write your own image filters.

Writing a Multiuse Data Loading Class

image with no caption

Just as our CustomLoader class extended the Loader class, we want to extend the URLLoader class and add similar automatic diagnostic features. We’ll call the new class CustomURLLoader and, as before, we’ll design it to use familiar syntax so you can switch between URLLoader and CustomURLLoader relatively easily. This class is very similar to CustomLoader in design and syntax, so our discussion will focus primarily on what makes it unique.

Writing the CustomURLLoader Class

Lines 1 through 9 declare the package, and import all the required classes. The classes required are similar to those required by CustomLoader, with the addition of the SecurityErrorEvent class and the substitution of the URLLoader class for Loader. We’ll discuss the SecurityErrorEvent class when we cover the listeners. Line 11 declares the class and extends URLLoader. Again, this makes available the accessible properties and methods of the URLLoader class. Lines 13 through 15 contain private properties also used in CustomLoader to contain the asset path, the logging Boolean, and a number that reports what percentage of the asset has loaded.

1    package com.learningactionscript3.loading {
2
3        import flash.events.Event;
4        import flash.events.HTTPStatusEvent;
5        import flash.events.IOErrorEvent;
6        import flash.events.ProgressEvent;
7        import flash.events.SecurityErrorEvent;
8        import flash.net.URLLoader;
9        import flash.net.URLRequest;
10
11        public class CustomURLLoader extends URLLoader {
12
13            private var _path:String;
14            private var _verbose:Boolean;
15            private var _loadedPercent:Number = 0;

The constructor is nearly identical to that of the CustomLoader class. Starting with their similarities, this class accepts the asset path string and Boolean for verbose logging as arguments during instantiation (lines 17 and 18), populates the related properties (lines 20 and 21), adds the needed listeners (line 24), and tries to load the asset if a path was provided (lines 26 through 31). The big difference between the two classes is that this class also accepts the format string argument, with a default value of “text” (line 19), and assigns that value to the dataFormat property of the class, inherited from URLLoader, (line 22).

16            //constructor
17            function CustomURLLoader(path:String=null,
18                                     verbose:Boolean=false,
19                                     format:String="text") {
20                _path = path;
21                _verbose = verbose;
22                this.dataFormat = format;
23
24                addListeners();
25
26                if (path != null) {
27                    try {
28                        this.load(new URLRequest(path));
29                    } catch (err:Error) {
30                        trace("URL load error:", err.message);
31                    }
32                }
33            }

The remainder of the class is also nearly identical to that of CustomLoader. Starting with the event listeners, the addListeners() and removeListeners() methods also add and remove listeners, respectively (lines 35 through 63). The INIT and UNLOAD listeners are absent, as they do not apply to URLLoader, and the SecurityErrorEvent.SECURITY_ERROR has been added (lines 47 through 49, and 61 through 62). The latter is dispatched when you attempt to load data from a URL outside the security sandbox used by the SWF, and calls the method in lines 85 through 87.

Flash Player security is a big topic, which is discussed in greater detail on the companion website. Put simply, however, not every asset can be loaded without permission. Notably, a SWF can’t readily access the user’s local file system and remote URLs at the same time unless permission is granted, nor can you load content from different domains without permission—typically granted with a cross-domain policy file, which is an XML file on the remote server, listing any IP addresses that are allowed access. As your experience grows, and you start to work on projects where either of these needs arise, you’ll want to leave ample time to study security issues. See the post “Security Overview” on the companion website for more information.

Note

When doing anything that might cause a possible security concern, including loading assets, test your work in a browser as often as is practical. Flash Professional is considered a trusted zone that is not susceptible to most Flash Player security issues. As a result you may think your file is working without security problems throughout development, only to find out at the last minute that restrictions do apply in the browser. The default settings of Flash Professional allow you to test in a browser easily using the Ctrl+F12 (Windows) or Cmd+F12 (Mac) keyboard shortcut.

Finally, the getter and setter (lines 93 through 99) are identical to those found in the CustomLoader class, returning the percentage of bytes loaded, and enabling or disabling the verbose logging feature, respectively.

34            //listeners
35            private function addListeners():void {
36                this.addEventListener(Event.OPEN,
37                                      onOpen, false, 0, true);
38                this.addEventListener(ProgressEvent.PROGRESS,
39                                      onProgress, false, 0, true);
40                this.addEventListener(HTTPStatusEvent.HTTP_STATUS,
41                                      onStatusEvent,
42                                      false, 0, true);
43                this.addEventListener(Event.COMPLETE,
44                                      onComplete, false, 0, true);
45                this.addEventListener(IOErrorEvent.IO_ERROR,
46                                      onIOError, false, 0, true);
47                this.addEventListener(SecurityErrorEvent.SECURITY_ERROR,
48                                      onSecError,
49                                      false, 0, true);
50            }
51
52            public function removeListeners():void {
53                this.removeEventListener(Event.OPEN, onOpen);
54                this.removeEventListener(ProgressEvent.PROGRESS,
55                                      onProgress);
56                this.removeEventListener(HTTPStatusEvent.HTTP_STATUS,
57                                      onStatusEvent);
58                this.removeEventListener(Event.COMPLETE, onComplete);
59                this.removeEventListener(IOErrorEvent.IO_ERROR,
60                                      onIOError);
61                this.removeEventListener(SecurityErrorEvent.SECURITY_ERROR,
62                                      onSecError);
63            }
64
65            private function onOpen(evt:Event):void {
66                if (_verbose) { trace("Loading begun:", _path); }
67            }
68
69            private function onProgress(evt:ProgressEvent):void {
70                _loadedPercent = evt.bytesLoaded / evt.bytesTotal;
71                if (_verbose) {
72                    trace("Loading", _path,
73                                      "-- progress (0-1):", _loadedPercent);
74                }
75            }
76
77            private function onStatusEvent(evt:HTTPStatusEvent):void {
78                if (_verbose) { trace("HTTP status:", evt.status); }
79            }
80
81            private function onComplete(evt:Event):void {
82                if (_verbose) { trace("Loading complete:", _path); }
83            }
84
85            private function onSecError(evt:SecurityErrorEvent):void {
86                trace("Security error:", evt.text);
87            }
88
89            private function onIOError(evt:IOErrorEvent):void {
90                trace("Loading error:", evt.text);
91            }
92
93            public function get percentLoaded():Number {
94                return _loadedPercent
95            }
96
97            public function set verbose(bool:Boolean):void {
98                _verbose = bool;
99            }
100        }
101    }

Note

As with the CustomLoader class, the companion website includes an alternate version of CustomURLLoader that overrides the load() method. This simplifies the use of both classes because their internal listeners—those responsible for the verbose logging—are added and removed automatically. See the post, “Overriding the load() Method in Custom Loader Classes,” at the companion website, http://www.LearningActionScript3.com.

Using the CustomURLLoader Class

As you might imagine from their complementary design, using the CustomURLLoader class is very similar to using the CustomLoader class. We’ll show examples for loading text, variables, and binary data.

Loading text

The following example, found in the load_text_custom.fla source file, is a simple use of the class. It passes the path of the text file into the class constructor to let the class handle the loading (lines 3 and 4), and it uses verbose logging so you can see what’s going on. Other than using our custom class and removing its internal listeners (line 10), it’s the same in every other respect as the basic text-loading example explained earlier in the chapter.

1    import com.learningactionscript3.loading.CustomURLLoader;
2
3    var ldrText:CustomURLLoader = new CustomURLLoader("lorem.txt",
4                                                      true);
5
6    ldrText.addEventListener(Event.COMPLETE, onComplete,
7                             false, 0, true);
8    function onComplete(evt:Event):void {
9        evt.target.removeEventListener(Event.COMPLETE, onComplete);
10        evt.target.removeListeners();
11        var txtFld:TextField = new TextField();
12        txtFld.x = txtFld.y = 20;
13        txtFld.width = 500;
14        txtFld.height = 350;
15        txtFld.multiline = txtFld.wordWrap = true;
16        txtFld.text = evt.target.data;
17        addChild(txtFld);
18    }

Loading variables

The next example, found in the load_vars_custom.fla source file, employs syntax similar to what you used with the URLLoader class. The class is instantiated with no arguments (line 3), the dataFormat property is set separately (line 4), and the load() method is called using a URLRequest instance (line 5).

Two things that are different than the previous variable loading example are the removal of the self-contained class listeners (line 11) and the fact that the event listener method demonstrates using a for..in loop (lines 12 through 14) to iterate through all variables, rather than retrieving their values by name.

1    import com.learningactionscript3.loading.CustomURLLoader;
2
3    var ldrVars:CustomURLLoader= new CustomURLLoader();
4    ldrVars.dataFormat = URLLoaderDataFormat.VARIABLES;
5    ldrVars.load(new URLRequest("vars.txt"));
6
7    ldrVars.addEventListener(Event.COMPLETE, onComplete,
8                             false, 0, true);
9    function onComplete(evt:Event):void {
10        evt.target.removeEventListener(Event.COMPLETE, onComplete);
11        evt.target.removeListeners();
12        for (var prop in evt.target.data) {
13            trace(prop + ": " + evt.target.data[prop]);
14        }
15    }

Loading binary data

image with no caption

The final use of our CustomURLLoader class will again demonstrate loading binary data. This time, however, we’ll load a Pixel Bender filter. Adobe developed Pixel Bender to allow users to program image processing filters using a C-based language. Filters are typically written using the Pixel Bender Toolkit (an integrated development environment created expressly for this purpose) and then used by other Adobe applications like Photoshop, AfterEffects, and Flash Player.

You don’t have to be able to write the filters to use them, however. Many filters exist under a variety of licenses, including open source, freeware, shareware, and commercial. One place to find Pixel Bender filters is the Adobe Pixel Bender Exchange. Visit http://www.adobe.com/cfusion/exchange/, select the Pixel Bender exchange, and then browse or search for filters that can be used with Flash.

Note

You can learn more about Pixel Bender from the Pixel Bender Developer Center: http://www.adobe.com/devnet/pixelbender/.

In this example, we’ll use the SquarePattern filter created by the talented Flash Platform evangelist, teacher, and developer Lee Brimelow. You can read about it at Lee’s blog, The Flash Blog, at http://blog.theflashblog.com/?p=432.

Note

Lee Brimelow also created the Pixel Bender Viewer, a tool that allows you to load Pixel Bender filters, experiment with their settings, and export them in a format compatible with Flash Player. For more information, see http://blog.theflashblog.com/?p=385.

In ActionScript, this process begins by creating a shader using the Shader class. A shader defines a function that executes on all the pixels of an image, one pixel at a time. Shaders can be used for filters, fills, blend modes, and even numeric calculations. The benefit of these efforts is that Pixel Bender shaders can improve performance of these processor-intensive tasks. In this example, we’ll create a filter using the ShaderFilter class.

The following class, CustomLoadBinaryExample.as, is a document class used by the accompanying CustomLoadBinaryExample.fla source file. It will use the CustomLoader class to import an image and add it to the display list, then load the SquarePattern filter using the CustomURLLoader class, and finally animate the filter using an enter frame event listener.

Lines 1 through 11 declare the package and import all the required classes. Line 13 declares the class, which extends MovieClip so it can be used as a document class, if desired. Lines 15 through 20 declare a set of private properties that will hold the CustomLoader’s LoaderInfo instance (line 15), the loaded image (line 16), a CustomURLLoader instance (line 17), the Pixel Bender Shader and ShaderFilter (lines 18 and 19), and a property to hold the changing filter values during animation (line 20).

The constructor (lines 22 through 29) then uses the CustomLoader class to load an image (lines 23 and 24) and create an event listener to respond to the COMPLETE event (lines 25 through 28).

1    package {
2
3        import flash.display.Bitmap;
4        import flash.display.LoaderInfo;
5        import flash.display.MovieClip;
6        import flash.display.Shader;
7        import flash.filters.ShaderFilter;
8        import flash.events.Event;
9        import flash.net.URLLoaderDataFormat;
10        import com.learningactionscript3.loading.CustomLoader;
11        import com.learningactionscript3.loading.CustomURLLoader;
12
13        public class CustomLoadBinaryExample extends MovieClip {
14
15            private var _ldrInfo:LoaderInfo;
16            private var _penguins:Bitmap;
17            private var _ldrBinary:CustomURLLoader;
18            private var _shader:Shader;
19            private var _shaderFilter:ShaderFilter;
20            private var _val:Number = 0;
21
22            public function CustomLoadBinaryExample() {
23                var jpgLoader:CustomLoader =
24                    new CustomLoader("penguins.jpg");
25                _ldrInfo = jpgLoader.contentLoaderInfo;
26                _ldrInfo.addEventListener(Event.COMPLETE,
27                                          onImgLoaded,
28                                          false, 0, true);
29            }

Once the image has loaded, the onImgLoaded() method (lines 31 through 44) is called. The COMPLETE event listener is removed from the CustomLoader’s LoaderInfo instance (lines 32 and 33), the class’s internal listeners are removed (line 34), and the loaded bitmap is then added to the display list (lines 35 and 36). Next, the CustomURLLoader class is used to load the Pixel Bender filter file as binary data (lines 38 through 40), and another COMPLETE listener is created (lines 41 through 43)—this time calling its method when the filter is completely loaded.

30            //load filter
31            private function onImgLoaded(evt:Event):void {
32                evt.target.removeEventListener(Event.COMPLETE,
33                                               onImgLoaded);
34                evt.target.loader.removeListeners();
35                _penguins = Bitmap(evt.target.content);
36                addChild(penguins);
37
38                _ldrBinary =
39                    new CustomURLLoader("squarepattern.pbj", true,
40                                        URLLoaderDataFormat.BINARY);
41                _ldrBinary.addEventListener(Event.COMPLETE,
42                                            onFilterLoaded,
43                                            false, 0, true);
44            }

When the filter file is loaded, the onFilterLoaded() method (lines 46 through 55) is called. The COMPLETE event listener is removed from the CustomURLLoader (lines 47 and 48), and the class’s internal listeners are removed on line 49. Next a Shader instance is created from the loaded Pixel Bender data, and a ShaderFilter instance is derived from the Shader instance. The last task of the method sets up the filter animation by creating an enter frame event listener (lines 53 through 54).

45            //create Shader and ShaderFilter
46            private function onFilterLoaded(evt:Event):void {
47                _ldrBinary.removeEventListener(Event.COMPLETE,
48                                               onFilterLoaded);
49                evt.target.removeListeners();
50                _shader = new Shader(evt.target.data);
51                _shaderFilter = new ShaderFilter(shader);
52
53                this.addEventListener(Event.ENTER_FRAME, onEnter,
54                                      false, 0, true);
55            }

Finally, the enter frame event listener method onEnter() (lines 57 through 66) animates the filter. First, the filter is assigned to the Bitmap instance’s filters property, as discussed in Chapter 9. Next the _val property is incremented (line 60). Then the _val property is used to update the SquarePattern’s amount property value. The property takes an array of three numbers: minimum, maximum, and default. We’ve set the maximum to 50, and the default to 0, and we’re incrementing the minimum by 1 every enter frame. When the value reaches 50, the event listener is removed, halting the animation (lines 62 through 65).

56            //adjust filter values
57            private function onEnter(evt:Event):void {
58                _penguins.filters = [_shaderFilter];
59
60                _val++;
61                _shader.data.amount.value = [_val, 50, 0];
62                if (_val >= 50) {
63                    this.removeEventListener(Event.ENTER_FRAME,
64                                             onEnter);
65                }
66            }
67        }
68    }

Communicating with Loaded SWFs

Now that you know how to load SWFs, let’s talk about communicating between them. For this discussion, we’ll reference the Loader class, but the ideas in this section apply equally to the CustomLoader class.

Note

To see the CustomLoader class used in this context, consult the nearly identical source files, communication_child_custom.fla and communication_parent_custom.fla. For these examples to work, the child SWF must exist before testing the parent SWF.

The key to communicating between a parent SWF created with ActionScript 3.0 and a loaded SWF created with ActionScript 3.0 is understanding the position of the Loader instance between the two SWFs. Within the parent, accessing the child SWF is straightforward because you need only do so through the Loader instance. The same is true in the other direction, from child to parent, but is less obvious to some. Just like when traversing the display list, you can use this.parent within a loaded child SWF to talk to its parent. However, this will refer to the Loader instance, not the SWF’s main timeline (or document class) scope.

Note

SWFs created with ActionScript 3.0 cannot talk directly to SWFs created with ActionScript 2.0 or ActionScript 1.0. If you must do this, such as when showcasing legacy projects in a new portfolio site, you can do so with a workaround that establishes a LocalConnection channel between the SWFs. For more information, see the “Sending Data from AVM2 to AVM1” post on the companion website.

The following examples, found in the communication_parent.fla and communication_child.fla source files, demonstrate several tasks you may need to perform when communicating between parent and child SWFs, including getting or setting properties, calling methods, and calling functions. This exercise shows communication in both directions. Both SWFs contain a simple movie clip animation, a function, and a variable. They both trace information to help you understand what’s happening when the parent SWF loads the child SWF into a Loader instance.

The child SWF

Lines 1 through 7 provide the code that is self-contained within the child SWF, which the parent will manipulate. Line 1 initially stops the animation so we can demonstrate the parent calling the MovieClip play() method. We’ll show you when this occurs in the parent script, but after loading, the animation should play. Line 3 creates and populates a string variable, the content of which states that it exists inside the child SWF. Lines 5 through 7 define a function that traces a string passed to it as an argument. This string will originate in the parent SWF to demonstrate calling a function in the child SWF.

Lines 9 through 25 contain the inter-SWF communication, but the conditional beginning in line 9 is necessary to prevent errors when testing the SWF prior to loading. The conditional simply checks to see if the parent of the SWF’s main timeline is the stage. As we discussed in Chapter 4 when covering the display list, there is only one stage and, when a SWF is on its own, its parent is the stage. If this is true, the child will trace [object Stage] in line 11, and show that the stage has no other parent by tracing null in line 12. We’ll discuss what happens when the SWF’s parent is not the stage after the code.

1    childAnimation.stop();
2
3    var stringMsg:String = "STRING INSIDE CHILD";
4
5    function childFunction(msg:String):void {
6        trace("traced from function within child:", msg);
7    }
8
9    if (this.parent == this.stage) {
10        trace("child without being loaded:");
11        trace(" my parent:", this.parent);
12        trace(" my parent's parent:", this.parent.parent);
13    } else {
14        trace("child communicating with parent:");
15        var parentLoader:Loader = Loader(this.parent);
16        var parentApp:MovieClip = MovieClip(this.parent.parent);
17        trace(" my parent:", parentLoader);
18        trace(" getting my parent's property:", parentLoader.x);
19        trace(" my parent's parent:", parentApp);
20        parentApp.stringMsg = "NEW STRING INSIDE PARENT";
21        trace(" my parent's parent's redefined variable:",
22            parentApp.stringMsg);
23        parentApp.parentFunction("message from child");
24        parentApp.parentAnimation.play();
25    }

If the child SWF’s parent is not the stage, lines 15 and 16 cast the parent to a Loader instance and the parent’s parent (which is the main timeline of the SWF doing the loading) to a MovieClip instance. Line 17 then traces the Loader instance, and line 18 traces a property of that Loader. Line 20 demonstrates setting a variable in another SWF by changing the string variable in the parent. (We’ll see that variable in a moment, but it’s equivalent to line 3 in the child). Lines 21 and 22 then get and trace that variable. Finally, line 23 calls a function in the parent (passing a string argument in the process), and line 24 plays the movie clip in the parent.

The parent SWF

The parent SWF requires no conditional, but is responsible for loading the child SWF. Lines 1 through 7 perform similar roles to the corresponding lines in the child SWF—initially stopping a movie clip animation, declaring and populating a string variable, and defining a function that accepts a string as an argument. The variable in line 3 is the same one redefined by the child SWF in its line 20, and the function in line 5 is the same one called by the child SWF in its lines 21 and 22.

Lines 9 through 15 should be familiar territory by now. They create a Loader instance, add it to the display list, load the child SWF, and create a COMPLETE event listener that calls the function in line 16 when the event is heard. Line 17 casts the content of the Loader (the child SWF) as a MovieClip, line 19 traces the child SWF’s variable, line 21 calls the child SWF’s function, and line 22 plays the child SWF’s movie clip.

1    parentAnimation.stop();
2
3    var stringMsg:String = "STRING INSIDE PARENT";
4
5    function parentFunction(msg:String):void {
6        trace("traced from within parent:", msg);
7    }
8
9    var ldr:Loader = new Loader();
10    addChild(ldr);
11    ldr.load(new URLRequest("communication_child.swf"));
12
13    ldr.contentLoaderInfo.addEventListener(Event.COMPLETE,
14                                           onComplete,
15                                           false, 0, true);
16    function onComplete(evt:Event):void {
17        var childSWF:MovieClip = MovieClip(ldr.content);
18        trace("
parent communicating with child:");
19        trace(" getting my child's variable:",
20            childSWF.stringMsg);
21        childSWF.childFunction("message from parent");
22        childSWF.childAnimation.play();
23    }

Note

The source files communication_parent_custom.fla and communication_child_custom.fla replicate the scripts in this section but use the CustomLoader class for all loading.

The companion website also contains an example of communication between parent and child SWF without using a Loader instance. See the post “SWF Communication without Going Through Loader.”

Additional Online Resources

We want to wrap up by drawing attention to two important loading-related issues that we’ve documented in detail online. The first is a workaround for a problem that occurs when loading SWFs that contain Text Layout Framework (TLF) assets (discussed in Chapter 10). The second is a third-party ActionScript package called LoaderMax that brings a lot of power and convenience to the loading process.

Loading SWFs with TLF Assets

TLF uses a Runtime Shared Library (RSL)—an external library of code with an .swz extension that’s loaded at runtime. If a user doesn’t already have the correct version of the RSL on his or her computer, the TLF asset will try to download it from the Adobe website. Failing that, a version of the RSL from the same directory as the SWF will be loaded.

Note

Runtime shared libraries can have a .swz extension if compressed, and a .swc extension if not compressed.

Because RSLs are external, it’s possible to experience a short delay when viewing TLF assets. (Ideally this occurs only the first time, as RSLs should be cached on your computer thereafter.) To compensate for this possible delay, Adobe included a preloader that’s automatically added to any SWF that uses TLF.

Note

If you ever see an animated line of five dots before a TLF asset displays, that’s its preloader at work.

Unfortunately, this setup causes problems after loading SWFs with TLF assets. The most common problem is that you can’t communicate between parent and child, as described in the Communicating with Loaded SWFs section of this chapter, because of the extra layers of loaders that are inserted into the display list by the TLF asset.

There are essentially two solutions to this problem, both of which are discussed on the companion website in the “Loading SWFs that Use TLF” post. The first is to compile the TLF Runtime Shared Library code into your SWF. This makes the entire setup internal, but also increases your SWF’s file size by about 120k. The second solution is to use Adobe’s new SafeLoader class.

The SafeLoader class is a replacement for the Loader class (it doesn’t extend Loader) and is available for download from the following Adobe Technote: http://kb2.adobe.com/cps/838/cpsid_83812.html. Its use is nearly identical to the Loader class, and you only really need to use it when you know you’re loading TLF assets. Sample code is provided with the class in the cited download. We’ll also use it in the XML navigation bar in Chapter 14.

The SafeLoader class was released soon after Flash Professional CS5 was released and may still have some issues to grapple with. We discuss such issues in the aforementioned companion website post, so be sure to review it before using the class.

TLF assets also affect preloading code designed to preload the SWF in which the code resides. That is, instead of loading an external asset, this kind of preloading code sits in frame 1 of the SWF and loops back to frame 1 until the SWF is fully loaded. Once the SWF is loaded, the code then moves the playhead on to the next frame.

Note

Flash Professional CS5 users can see an example of a self-preloader in the templates that ship with the application. Select the File✓New menu option, and then select the Templates tab in the dialog box that appears. Choose the Sample Files category and select the Preloader for SWF template. You can then see the preloading code in frame 1.

If you are not using Flash Professional CS5, you can search the web using the phrase “AS3 preloader internal” for many examples to find one that suits your coding style. Because links change often, the companion website will provide a link to both a class-based and timeline-based example in the cited post.

GreenSock’s LoaderMax

A fitting end to this chapter is a quick blurb about LoaderMax. Brought to you by GreenSock, the makers of TweenLite, LoaderMax is the crème de la crème of ActionScript 3.0 loading libraries. Adding as little as 7k to your SWF (depending on which classes you need to use), LoaderMax loads SWFs, images, XML, videos, MP3s, CSS, data, and more. LoaderMax simplifies and enhances loading the way TweenLite simplifies and enhances tweening. For example, here are some of the things LoaderMax can do:

  • Build loaders in a variety of ways, including single-item loaders from nothing more than a String path (LoaderMax can automatically determine which type of loader to use based on the file extension) and loader queues automatically assembled from XML documents

  • Build a queue that intelligently loads assets in the order specified but that can easily reprioritize the queued assets on the fly

  • Show progress of individual loaders or all loaders as a group

  • Easily add robust event listeners, including multiple events in a single line of code

  • Integrate subloaders (LoaderMax instances that exist inside an asset being loaded) with the overall progress and event model of the main loader

  • Provide an alternate URL that will automatically be used in the event the first URL fails

  • Pause and resume loads in progress

  • Circumvent existing ActionScript loading and unloading issues with improved garbage collection, including properly loading SWFs with TLF assets

  • Optionally manipulate many display characteristics include automatic scaling, image smoothing, centering registration points, and more

  • Operationally control video and MP3 assets, including methods that play, pause, and go to specific time; properties that get or set volume, time, and duration; and events that monitor playback progress and more

  • Provide a substantial number of shared properties, methods, and events to all loader types improving consistency and saving lots of manual labor.

LoaderMax is easy to learn and use, particularly after you’re familiar with the ActionScript 3.0 loading process. Ideally, this chapter has provided you with the groundwork to get you started, and you can consider using LoaderMax for your next project. For more information, visit http://www.LoaderMax.com.

Note

See the “Meet LoaderMax” post at the companion website for additional information and source code.

What’s Next?

Throughout this book, we’ve demonstrated a few examples of loading external assets. Previously, we discussed loading HTML and CSS (Chapter 10), sound (Chapter 11), and video (Chapter 12). In this chapter, we focused on loading SWF and image assets, as well as text, URL variables, and binary data. We also extended the Loader and URLLoader classes to add some basic diagnostic features to make it easier to check on your loading efforts. Finally, we discussed communication with loaded SWFs and provided a few online resources that touch on additional loading-related topics. With this information as a head start, you should be able to begin working with just about any basic external asset, and begin explorations into intermediate and advanced loading issues.

Next we’re going to cover XML, which is among the most important standard formats used for data exchange, and E4X, the dramatically simplified approach to working with XML in ActionScript. XML is very widely used and enables a significant leg up over name-value pairs when it comes to structured data and large data sizes.

In the next chapter, we’ll cover:

  • The basics of the XML format

  • Reading, writing, and editing XML data

  • Loading XML assets using the CustomURLLoader class from this chapter

  • XML communication with servers and other peers

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.8.90