y = 10; 34 return sp; 35 } Loading Data While the Loader class will load visual assets, data such as text, URL vari-ables, and even binary data, is loaded with the URLLoader class.. Just
Trang 1load() method The only other difference between this script and the
exam-ple shown in the “Loading SWFs” section is in line 11 Because the examexam-ple
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 }
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
func-tion 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 );
N OT E
The event listeners in the example FLA files are not the same as the event lis-teners 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
Trang 213 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 }
Loading Data
While the Loader class will load visual assets, data such as text, URL vari-ables, 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 program-ming 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
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
N OT E
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
possi-ble, 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.
N OT E
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.
Trang 3through 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-name-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
val-ues 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 }
Trang 4The 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 data-Format 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
Writing a Multiuse Data Loading Class
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 addi-tion of the SecurityErrorEvent class and the substitution of the URLLoader
class for Loader We’ll discuss the SecurityErrorEvent class when we cover
N OT E
Pixel Bender is an Adobe technology
that lets you use a programming
lan-guage based on C to write your own
image filters
Pu sh
You rself!
Trang 5the 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 ;
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
dif-ference 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
Trang 6to 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 with-out 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
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,
N OT E
When doing anything that might cause
a possible security concern,
includ-ing loadinclud-ing 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)
key-board shortcut.
Trang 773 " 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 }
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
con-structor 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" ,
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;
N OT E
As with the CustomLoader class, the companion website includes an alter-nate 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
Trang 813 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 instan-tiated 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
The final use of our CustomURLLoader class will again demonstrate loading binary data This time, however, we’ll load a Pixel Bender filter Adobe devel-oped 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
Pu sh
You rself!
N OT E
You can learn more about Pixel Bender
from the Pixel Bender Developer
Center: http://www.adobe.com/devnet/
pixelbender/
Trang 9In 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
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
proper-ties 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" );
N OT E
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
Trang 1025 _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,