Loading SWFs and Images There are a few ways to load SWFs or images at runtime, but you’ll com-monly use the Loader class in one way or another.. To simplify the process of loading these
Trang 1IN THIS PART
Chapter 13
Loading Assets
Chapter 14
XML and E4X
Part V homes in on two of the possible input and output methods used for
transferring data and assets in the Flash world Chapter 13 covers several
ways to load external assets It also includes a discussion of text, with an
in-depth look at loading variables Similar to the text-loading example, the
chapter takes a close look at best practices for loading external SWF and
image formats The chapter wraps up with a look at communicating with
loaded SWFs
Chapter 14 provides a detailed look at what may be the most common format
for structured data exchange: XML In addition to the creation of XML
docu-ments in their own right, the chapter discusses reading, writing, and editing
XML on the fly Finally, the chapter covers XML communication between
client and server
Download from Wow! eBook <www.wowebook.com>
Trang 3IN 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
librar-ies 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
bina-ry 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
LoadIng assets
Download from Wow! eBook <www.wowebook.com>
Trang 4Part V: Input/Output
362
Loading SWFs and Images
• 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 run-time, which presents its own unique difficulties We’ll point to two solu-tions, 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 com-monly 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 proper-ties 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
cre-ates 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 traf-fics all information about the content of the Loader
For example, if you attached an event listener to the Loader instance that lis-tened 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 virtu-ally 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
Download from Wow! eBook <www.wowebook.com>
Trang 5Loading SWFs and Images
Chapter 13: Loading Assets 363
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
add-ing 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 }
Download from Wow! eBook <www.wowebook.com>
Trang 6Part V: Input/Output
364
Loading SWFs and Images
Writing a Multiuse SWF and Image Loading Class
The previous examples presented the simplest syntax for loading visual assets Typical loading tasks are more involved, because they include addi-tional 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 fea-tures 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
Writing the CustomLoader Class
The class we want to write is called CustomLoader and is in the in the load-ing directory of the learnload-ingactionscript3 package we’ve been developload-ing
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 dis-cuss 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 acces-sible 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)
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;
Pu sh
You rself!
N OT E
You can even type the new class as
Loader when creating instances, so your
code can be more flexible.
N OT E
See Chapter 6 for more information
about inheritance.
Download from Wow! eBook <www.wowebook.com>
Trang 7Loading SWFs and Images
Chapter 13: Loading Assets 365
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
construc-tor 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
generi-cally, 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
descrip-tive 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
Download from Wow! eBook <www.wowebook.com>
Trang 8Part V: Input/Output
366
Loading SWFs and Images
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
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
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,
N OT E
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
infor-mation, see the “Trapping Uncaught
Errors” post at the companion website,
http://www.LearningActionScript3.com.
N OT E
Another way to maintain your
listen-ers 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
over-ride 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
Download from Wow! eBook <www.wowebook.com>
Trang 9Loading SWFs and Images
Chapter 13: Loading Assets 367
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
condi-tional 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
load-ed 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
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) {
N OT E
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.
Download from Wow! eBook <www.wowebook.com>
Trang 10Part V: Input/Output
368
Loading SWFs and Images
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:\n" , 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
class-es use similar syntax The following examplclass-es replicate the previous examplclass-es 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
Download from Wow! eBook <www.wowebook.com>