JETZT ONLINE BESTELLEN
Solutions for Flash Platform and Flex Application Developers
First Edition Oktober 2006
ISBN 978-0-596-52695-5
586 Seiten
EUR32.00
Weitere Informationen zu diesem Buch
Inhaltsverzeichnis
- Chapter 1: ActionScript Basics
- InhaltsvorschauUsing ActionScript, you can create Flash applications that do just about anything you can imagine. But before launching into the vast possibilities, let’s start with the basic foundation. The good news is that ActionScript commands follow a well-defined pattern, sharing similar syntax, structure, and concepts. Mastering the fundamental grammar puts you well on the way to mastering ActionScript.This chapter addresses the frequent tasks and problems that relate to core ActionScript knowledge. Whether you are a beginner or master—or somewhere in between—these recipes help you handle situations that arise in every ActionScript project.This book assumes that you have obtained a copy of Flex Builder 2 and have successfully installed it on your computer. It’s also helpful if you have some experience using a previous version of ActionScript as well.When you launch Flex Builder 2, the Eclipse IDE should start up and present you with a welcome screen. You are presented with various options to get started and more information about Flex and ActionScript 3, such as links to documentation, tutorials, and more. You can close that screen by clicking on the small “x” on its tab. Now you are in the Eclipse IDE itself, ready to start coding; but where do you go from here?Flex Builder 2 allows you to create three kinds of projects: a Flex project, Flex Library project, and an ActionScript project. The difference is that Flex projects have access to the entire Flex Framework, which includes all of the Flex components, layout management, transitions, styles, themes, data binding, and all the other stuff that goes into making a Flex Rich Internet Application. Flex applications are written in MXML (a form of XML), which describes the layout and relationship between components. They use ActionScript for their business logic. Although you can use the ActionScript knowledge you learn from here in Flex applications you write, this book concentrates on ActionScript projects exclusively.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- Introduction
- InhaltsvorschauUsing ActionScript, you can create Flash applications that do just about anything you can imagine. But before launching into the vast possibilities, let’s start with the basic foundation. The good news is that ActionScript commands follow a well-defined pattern, sharing similar syntax, structure, and concepts. Mastering the fundamental grammar puts you well on the way to mastering ActionScript.This chapter addresses the frequent tasks and problems that relate to core ActionScript knowledge. Whether you are a beginner or master—or somewhere in between—these recipes help you handle situations that arise in every ActionScript project.This book assumes that you have obtained a copy of Flex Builder 2 and have successfully installed it on your computer. It’s also helpful if you have some experience using a previous version of ActionScript as well.When you launch Flex Builder 2, the Eclipse IDE should start up and present you with a welcome screen. You are presented with various options to get started and more information about Flex and ActionScript 3, such as links to documentation, tutorials, and more. You can close that screen by clicking on the small “x” on its tab. Now you are in the Eclipse IDE itself, ready to start coding; but where do you go from here?Flex Builder 2 allows you to create three kinds of projects: a Flex project, Flex Library project, and an ActionScript project. The difference is that Flex projects have access to the entire Flex Framework, which includes all of the Flex components, layout management, transitions, styles, themes, data binding, and all the other stuff that goes into making a Flex Rich Internet Application. Flex applications are written in MXML (a form of XML), which describes the layout and relationship between components. They use ActionScript for their business logic. Although you can use the ActionScript knowledge you learn from here in Flex applications you write, this book concentrates on ActionScript projects exclusively.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- Creating an ActionScript Project
- InhaltsvorschauYou’ve launched Flex Builder 2 and want to create an ActionScript project.Use the New ActionScript Project Wizard to set up your project.An ActionScript project usually consists of at least one class file and a folder named bin that contains the SWF and HTML files output by the compiler. It also consists of a lot of internal settings to let the compiler know where everything is and how to compile it all. Flex Builder 2 takes care of most of this for you when you use the New ActionScript Project Wizard. There are a few ways to start this wizard. You can use the menu File→New→ActionScript Project, or you can click on the New button in the top-right corner and select ActionScript Project from the list of available projects there. You can also click the small arrow next to the New button, which gives you the same list.Whichever route you take to get there, you should wind up with the New ActionScript Project Wizard. Here you’ll be prompted to type in a name for your project, such as ExampleApplication. Once you’ve created the project, you’ll notice that the main application file is automatically set to the same name as the project name, with a .as extension.Clicking the Next button gives you the opportunity to set custom class paths, additional libraries, and specify your output folder to something than the default bin. For now, you don’t need to do anything here, so just press Finish to exit the wizard.Flex Builder 2 now creates the necessary folders and files and applies all the default compiler settings for your project. In the Navigator view, you should now see a ExampleApplication project, which contains an empty bin folder and a ExampleApplication.as class file. Note that it has created this main class file for you automatically and has opened it up for editing in the code view. Also, in the Outline view, you can see a tree representation of the class, including its methods, properties, and any import statements.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- Customizing the Properties of an Application
- InhaltsvorschauYou want to change the dimensions of the output .swf, or its background color, frame rate, etc.Specify properties as ActionScript Compiler arguments or metadata in the class file.Unlike earlier versions of Flash, the ActionScript 3.0 compiler is actually a command-line compiler. Technically, you could create all your classes and directories and run the compiler from the command line with a long chain of parameters. However, it’s much easier to let Eclipse keep track of all those parameters, add all of them, and run the compiler when you tell it to run.When you create a new ActionScript project, it sets up default parameters that result in an 500×375 pixel .swf, with a frame rate of 24 f rames per second (fps) and that blue background color you’ve seen. You can change any of these settings and many more. As you might expect, there are a few different ways to do this.The first way to change compiler settings is to set the ActionScript compiler arguments. You do this by right-clicking on the project in the Navigator view and choosing Properties from the menu. Next, choose ActionScript Compiler from the list on the left. This allows you to change several aspects of how the compiler does its job. Look for the text field labeled “Additional compiler arguments.” Anything you type in this text field is passed directly to the command-line compiler as an argument.Here are the most common arguments you will probably be using:
-default-size width height -default-background-color color -default-frame-rate fps
You enter them exactly as presented, with numbers for arguments, like so:-default-size 800 600 -default-background-color 0xffffff -default-frame-rate 31
The first example sets the resulting size of the resulting .swf to 800×600 pixels. The second sets its background to white, and the last sets its frame rate to 31 fps. Multiple arguments would just be placed one after the other on the same line, like so:Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Where to Place ActionScript Code
- InhaltsvorschauYou have a new ActionScript project and need to know where to put the code for it to execute properly.Place ActionScript code in the constructor and additional methods of the class.In ActionScript 1.0 and 2.0, you had many choices as to where to place your code: on the timeline, on buttons and movie clips, on the timeline of movie clips, in external .as files referenced with #include, or as external class files. ActionScript 3.0 is completely class-based, so all code must be placed in methods of your project’s classes.When you create a new ActionScript project, the main class is automatically created, and opened in the Code view. It should look something like this:
package { import flash.display.Sprite; public class ExampleApplication extends Sprite { public function ExampleApplication( ) { } } }Even if you are familiar with classes in ActionScript 2.0, there are some new things here. There is a lot more information on this subject in Chapter 2, but let’s go through the basics here.The first thing you’ll notice is the word package at the top of the code listing. Packages are used to group classes of associated functionality together. In ActionScript 2.0, packages were inferred through the directory structure used to hold the class files. In ActionScript 3.0, however, you must explicitly specify packages. For example, you could have apackageof utility classes. This would be declared like so:package com.as3cb.utils { }If you don’t specify a package name, your class is created in the default, top-level package. You should still include the package keyword and braces.Next, place anyimportstatements. Importing a class makes that class available to the code in the file and sets up a shortcut so you don’t have to type the full package name every time you want to refer to that class. For example, you can use the followingEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - How to Trace a Message
- InhaltsvorschauYou need to trace out a message or the value of some data at runtime.Use the trace function, pass the data to it, run your application, and look for a message in the Console in Eclipse.You can trace out a message, the value of a variable, or just about any other data using trace, just as you would in earlier versions of ActionScript. Some examples:
trace("Hello, world"); trace(userName); trace("My name is " + userName + ".");Since the .swf is now launched in an external browser, it might seem that there is no way to capture the output of these trace statements. Fortunately, it is possible, and this functionality has been built in to Flex Builder 2 via the Console view. The Console view is the equivalent of the Output panel in the Flash IDE. Although it is not open when you first start Eclipse, it appears when needed.The only requirement to using trace and the Console view is that you use Debug to test your application. Doing so includes extra features in the .swf that allows it to communicate back to the Console behind the scenes and pass any messages you trace. The following class creates a variable, assigns a value to it, and then traces it, along with some other string data:package { import flash.display.Sprite; public class ExampleApplication extends Sprite { public function ExampleApplication( ) { var userName:String = "Bill Smith"; trace("My name is " + userName + "."); } } }Now when you debug your application, it launches as usual in your default browser. Close the browser and switch back to Eclipse. You will see that the Console view is now open and has displayed the data you traced out.When you launch the debug version of an application, you must have the debug version of Flash Player installed. If you don’t have the debug version of Flash Player, you’ll see an error message notifying you, and you’ll have to download and install it fromEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Handling Events
- InhaltsvorschauYou want to have some code repeatedly execute.Add a listener to the enterFrame event and assign a method as a handler.In ActionScript 2.0 handling the enterFrame event was quite simple. You just had to create a timeline function called onEnterFrame and it was automatically called each time a new frame began. In ActionScript 3.0, you have much more control over the various events in a .swf, but a little more work is required to access them.If you are familiar with the EventDispatcher class from ActionScript 2.0, you should be right at home with ActionScript 3.0’s method of handling events. In fact, EventDispatcher has graduated from being an externally defined class to being the base class for all interactive objects, such as sprites.To respond to the enterFrame event, you have to tell your application to listen for that event and specify which method you want to be called when the event occurs. This is done with the addEventListener method, which is defined as follows:
addEventListener(type:String, listener:Function)
There are additional parameters you can look up in the help files, but this is the minimum implementation.The type parameter is the type of event you want to listen to. In this case, it would be the string,"enterFrame". However, using string literals like that opens your code to errors that the compiler cannot catch. If you accidentally typed"enterFrane", for example, your application would simply listen for an"enterFrane"event. To guard against this, it is recommended that you use the static properties of the Event class. You should already have the Event class imported, so you can call the addEventListener method as follows:addEventListener(Event.ENTER_FRAME, onEnterFrame);
Now if you accidentally typedEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Responding to Mouse and Key Events
- InhaltsvorschauYou want to do something in response to a mouse or keyboard action.Listen for and handle mouse or key events.Handling mouse and key events is very similar to handling the enterFrame event, as discussed in the Recipe 1.5, but does require a little work. For mouse events, the main application class will not receive these directly, so it must listen for them on another object in the display list. (For a complete discussion of the display list, see Chapter 5.) The following example creates a sprite, adds it to the display list, and draws a rectangle in it:
package { import flash.display.Sprite; import flash.events.MouseEvent; public class ExampleApplication extends Sprite { private var _sprite:Sprite; public function ExampleApplication( ) { _sprite = new Sprite( ); addChild(_sprite); _sprite.graphics.beginFill(0xffffff); _sprite.graphics.drawRect(0, 0, 400, 400); _sprite.graphics.endFill( );Note that the mouse event names are defined in the MouseEvent class, and the handler methods get passed an instance of the MouseEvent class, so you’ll need to import that class. Then you can add mouse listeners to this sprite:_sprite.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); _sprite.addEventListener(MouseEvent.MOUSE_UP, onMouseUp); }Next, define the two handler methods,onMouseDownandonMouseUp:private function onMouseDown(event:MouseEvent):void { _sprite.graphics.lineStyle(1, 0, 1); _sprite.graphics.moveTo(mouseX, mouseY); _sprite.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove); } private function onMouseUp(event:MouseEvent):void { _sprite.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove); }Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Using Mathematical Operators
- InhaltsvorschauYou want to modify something over time, such as the rotation or position of a sprite.Use the compound assignment operators to change a variable or property in increments; or, if incrementing or decrementing by one, use the prefix or postfix increment or decrement operators.Often you’ll want the new value of a variable or property to depend on the previous value. For example, you might want to move a sprite to a new position that is 10 pixels to the right of its current position.In an assignment statement—any statement using the assignment operator (an equals sign )—the expression to the right of the equals sign is evaluated and the result is stored in the variable or property on the left side. Therefore, you can modify the value of a variable in an expression on the right side of the equation and assign that new value to the very same variable on the left side of the equation.Although the following may look strange to those who remember basic algebra, it is very common for a variable to be set equal to itself plus some number:
// Add 6 to the current value of quantity, and assign that new // value back to quantity. For example, if quantity was 4, this // statement sets it to 10. quantity = quantity + 6;
However, when performing mathematical operations, it is often more convenient to use one of the compound assignment operators, which combine a mathematical operator with the assignment operator. The+=,-=,*=, and/=operators are the most prevalent compound assignment operators. When you use one of these compound assignment operators, the value on the right side of the assignment operator is added to, subtracted from, multiplied by, or divided into the value of the variable on the left, and the new value is assigned to the same variable. The following are a few examples of equivalent statements.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Checking Equality or Comparing Values
- InhaltsvorschauYou want to check if two values are equal.Use the equality (or inequality) or strict equality (or strict inequality) operator to compare two values. To check whether a value is a valid number, use isNaN( ).Equality expressions always return a Boolean value indicating whether the two values are equal. The equality (and inequality) operators come in both regular and strict flavors. The regular equality and inequality operators check whether the two expressions being compared can be resolved to the same value after converting them to the same datatype. For example, note that the string “6” and the number 6 are considered equal because the string “6” is converted to the number 6 before comparison:
trace(5 == 6); // Displays: false trace(6 == 6); // Displays: true trace(6 == "6"); // Displays: true trace(5 == "6"); // Displays: false
Note that in a project with default settings, the previous code example won’t even compile. That’s because it is compiled with astrictflag, causing the compiler to be more exact in checking datatypes at compile time. It complains that it is being asked to compare an int with a String. To turn off thestrictflag, go to the ActionScript Compiler section of the project’s properties, and uncheck the box next to “Enable compile-time type checking (-strict)”. It is suggested, however, that you leave this option on for most projects, as it gives you better protection against inadvertent errors.The logical inequality operator (!=) returnsfalseif two values are equal andtrueif they aren’t. If necessary, the operands are converted to the same datatype before the comparison:trace(5 != 6); // Displays: true trace(6 != 6); // Displays: false trace(6 != "6"); // Displays: false trace(5 != "6"); // Displays: true
Again, this example only compiles ifEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Performing Actions Conditionally
- InhaltsvorschauYou want to perform some action only when a condition is true.Use an if or a switch statement.You often need your ActionScript code to make decisions, such as whether to execute a particular action or group of actions. To execute some action under certain circumstances, use one of ActionScript’s conditional statements: if, switch, or the ternary conditional operator (
? :).Conditional statements allow you to make logical decisions, and you’ll learn from experience which is more appropriate for a given situation. For example, the if statement is most appropriate when you want to tell a Flash movie to do something only when a certain condition is met (e.g., when the condition istrue). When you have several possible conditions to test, you can use the switch statement instead. And you can use Flash’s ternary conditional operator to perform conditional checking and assignment on a single line.First let’s look at the if statement. Of the conditional statements in ActionScript, the if statement is the most important to understand. In its most basic form, an if statement includes the keywordiffollowed by the test expression whose truthfulness you want to evaluate to determine which action or actions to execute. The test expression must be in parentheses and the statement(s) to be executed should be within curly braces (the latter is mandatory if there is more than one statement in the statement block).Here we check whetheranimalNamecontains the word “turtle.” This might be used to check whether the user answered a quiz question correctly (here,animalNameis a variable assumed to contain the user’s answer). Note that the double equals sign (==) is used to test whether two items are equal. It should not be confused with the single equals sign (Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Performing Complex Conditional Testing
- InhaltsvorschauYou want to make a decision based on multiple conditions.Use the logical AND (
&&), OR (||), and NOT (!) operators to create compound conditional statements.Many statements in ActionScript can involve conditional expressions, including if, while, and for statements, and statements using the ternary conditional operator. To test whether two conditions are both true, use the logical AND operator,&&, as follows (see Chapter 14 for details on working with dates):// Check if today is April 17th. var current:Date = new Date( ); if (current.getDate( ) == 17 && current.getMonth( ) == 3) { trace ("Happy Birthday, Bruce!"); }You can add extra parentheses to make the logic more apparent:// Check if today is April 17th. if ((current.getDate( ) == 17) && (current.getMonth( ) == 3)) { trace ("Happy Birthday, Bruce!"); }Here we use the logical OR operator,||, to test whether either condition is true:// Check if it is a weekend. if ((current.getDay( ) == 0) || (current.getDay( ) == 6) ) { trace ("Why are you working on a weekend?"); }You can also use a logical NOT operator,!, to check if a condition is not true:// Check to see if the name is not Bruce. if (!(userName == "Bruce")) { trace ("This application knows only Bruce's birthday."); }The preceding example could be rewritten using the inequality operator,!=:if (userName != "Bruce") { trace ("This application knows only Bruce's birthday."); }Any Boolean value, or an expression that converts to a Boolean, can be used as the test condition:// Check to see if a sprite is visible. If so, display a // message. This condition is shorthand for _sprite.visible == true if (_sprite.visible) { trace("The sprite is visible."); }The logical NOT operator is often used to check if something isEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Repeating an Operation Many Times
- InhaltsvorschauYou want to perform some task multiple times within a single frame.Use a looping statement to perform the same task multiple times within a single frame. For example, you can use a for statement:
for (var i:int = 0; i < 10; i++) { // Display the value of i. trace(i); }When you want to execute the same action (or slight variations thereof) multiple times within a single frame, use a looping statement to make your code more succinct, easier to read, and easier to update. You can use either a while or a for statement for this purpose, but generally a for statement is a better choice. Both statements achieve the same result, but the for statement is more compact and more familiar to most programmers.The syntax of a for statement consists of five basic parts:- The
forkeyword -
Every for statement must begin with a
forkeyword. - Initialization expression
-
Loop typically employs an index variable (a loop counter) that is initialized when the statement is first encountered. The initialization is performed only once regardless of how many times the loop is repeated.
- Test expression
-
The loop should include a test expression that returns either
trueorfalse. The test expression is evaluated once each time through the loop. Generally, the test expression compares the index variable to another value, such as a maximum number of loop iterations. The overall expression must evaluate totruefor the for statement’s body to execute (contrast this with a do...while loop, which executes at least once, even if the test expression is
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - The
- Repeating a Task over Time
- InhaltsvorschauYou want to perform some action or actions over time.Use the Timer class. Alternatively, listen for the enterFrame event of a sprite.The Timer class is new to ActionScript 3.0, and is recommended over the earlier setInterval( ) and setTimeout( ) functions. When you create an instance of the Timer class, it fires timer events at regular intervals. You can specify the delay between events and how many times you want the events to fire in the Timer constructor:
var timer:Timer = new Timer(delay, repeatCount);
You use addEventListener to set up a method to handle these events. After you create the timer and set up a listener, use its start( ) method to start it and stop( ) to stop it.The Timer class is part of the flash.utils package, and there is also a TimerEvent class in the flash.events package, so those need to be imported:package { import flash.display.Sprite; import flash.events.TimerEvent; import flash.utils.Timer; public class ExampleApplication extends Sprite { // Declare and initialize a variable to store the value // of the previous timer reading. private var _PreviousTime:Number = 0; public function ExampleApplication( ) { var tTimer:Timer = new Timer(500, 10); tTimer.addEventListener(TimerEvent.TIMER, onTimer); tTimer.start( ); } private function onTimer(event:TimerEvent):void { // Output the difference between the current timer value and // its value from the last time the function was called. trace(flash.utils.getTimer( ) - _PreviousTime); _PreviousTime = flash.utils.getTimer( ); } } }The getTimer( ) function (previously a top-level function), has been moved to the flash.utils package as well. This simply returns the number of milliseconds since the application started.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Creating Reusable Code
- InhaltsvorschauYou want to perform a series of actions at various times without duplicating code unnecessarily throughout your movie.Create a method and then call (i.e., invoke) it by name whenever you need to execute those actions. When a function is a member of a class, it is often called a method.Here is how to create a method of a class:
accessModifier function functionName ( ):ReturnDataType { // Statements go here. }
To call (i.e., execute) the named method, refer to it by name, such as:functionName( );Grouping statements into a method allows you to define the method once but execute it as many times as you’d like. This is useful when you need to perform similar actions at various times without duplicating the same code in multiple places. Keeping your code centralized in methods makes it easier to understand (because you can write the method once and then ignore the details when using it) and easier to maintain (because you can make changes in one place rather than in multiple places).Like class variables, methods can be declared with access modifiers. These determine which other classes are able to call the methods. The available access modifiers are:private-
Can only be accessed from within the class itself.
protected-
Can be accessed by the class or any subclass. This is instance-based. In other words, an instance of a class can access its own protected members or those of its superclasses. It cannot access protected members on other instances of the same class.
internal-
Can be accessed by the class or any class within the same package.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Generalizing a Method to Enhance Reusability
- InhaltsvorschauYou want to perform slight variations of an action without having to duplicate multiple lines of code to accommodate minor differences.Add parameters to your method to make it flexible enough to perform slightly different actions when invoked rather than performing exactly the same action or producing the same result each time.Define the parameters that account for the variability in what you want the method to do:
private function average (a:Number, b:Number, c:Number):void { trace("The average is " + (c + b + c)/3); }If you don’t know the exact number of parameters the method will receive, use the built-inargumentsarray to handle a variable number of parameters.A method that doesn’t accept parameters generally does exactly the same result each time it is invoked. However, you will often need to perform almost exactly the same actions as an existing method, but with minor variations. Duplicating the entire method and then making minor changes to the second version is a bad idea in most cases. Usually, it makes your code harder to maintain and understand. More importantly, you’ll usually find that you need not only two variations but many variations of the method. It can be unnecessarily difficult to maintain five or six variations of what should ideally be wrapped into a single method. The trick is to create a single method that can accept different values to operate on.For example, let’s say you have an average( ) method for averaging a set of numbers. Instead of having it always average the same two numbers, you want to specify arbitrary values to be averaged each time it is invoked. This can be accomplished with parameters.The most common way to work with parameters is to list them within the parentheses in the method declaration. The parameter names should be separated by commas, and when you invoke the method you should pass it a comma-delimited list of arguments that corresponds to the parameters it expects.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Exiting a Method
- InhaltsvorschauYou want to exit a method.Methods terminate automatically after the last statement within the method executes. Use a return statement to exit a method before reaching its end.The return statement exits the current method and the ActionScript interpreter continues execution of the code that initially invoked the method. Any statements within the method body that follow a return statement are ignored.
private function sampleFunction ( ):void { return; trace("Never called"); } // Called from within another method: sampleFunction( ); // Execution continues here after returning from the sampleFuction( ) invocationIn the preceding example, the return statement causes the method to terminate before performing any actions, so it isn’t a very useful method. More commonly, you will use a return statement to exit a method under certain conditions. This example exits the method if the password is wrong:private function checkPassword (password:String):void { // If password is not "SimonSays", exit the function. if (password != "SimonSays") { return; } // Otherwise, perform the rest of the actions. showForm ("TreasureMap"); } // This method call uses the wrong password, so the // function exits. checkPassword("MotherMayI"); // This method call uses the correct password, so the function // shows the TreasureMap form. checkPassword("SimonSays");In the preceding example, you may notice that the method is declared asvoid, yet it is possible to use a return statement within the method without getting a compiler error. When a return statement is used simply to exit from a method, it is valid within a method declared asvoid.In ActionScript 2.0, the function wasVoid. In ActionScript 3.0, it is lowercasevoid.However, if you attempt to actually return a value in such a method, the compiler generates an error.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Obtaining the Result of a Method
- InhaltsvorschauYou want to perform some method and return the results to the statement that invoked the function.Use a return statement that specifies the value to return.When used without any parameters, the return statement simply terminates a method. However, any value specified after the
returnkeyword is returned to statement that invoked the method. Usually, the returned value is stored in a variable for later use. The datatype of the return value must match the return type of the method:private function average (a:Number, b:Number):Number { return (a + b)/2; }Now we can call the average( ) method and store the result in a variable and use the result in some way.var playerScore:Number = average(6, 10); trace("The player's average score is " + playerScore);You can use the return value of a method, without storing it in a variable, by passing it as a parameter to another function, such as:trace("The player's average score is " + average(6, 10));Note, however, that if you do nothing with the return value of the function, the result is effectively lost. For example, this statement has no detectable benefit because the result is never displayed or used in any way:average(6, 10);
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Handling Errors
- InhaltsvorschauYou want to programmatically detect when certain errors occur and handle them using code.Use a throw statement to throw an error when it is detected. Place any potentially error-generating code within a try block, and then have one or more corresponding catch blocks to handle possible errors.Flash Player 8.5 supports a try/catch methodology for handling errors in ActionScript. That means you can write code that can intelligently deal with certain error types should they occur. While you cannot handle syntax errors (the .swf won’t even compile in that case), you can handle most other error types, such as missing or invalid data. The benefit is that you can attempt to resolve the situation programmatically.An example may help to illustrate when and how you might use try/catch methodology: Consider an application that draws a rectangle based on user-input dimensions. To draw a rectangle within the application, you want to have certain range limitations on the dimensions the user can input. For example, you may want to make sure the values are defined, valid numeric values greater than 1 and less than 200. While there are certainly ways you can work to ensure the quality and validity of the data before even attempting to draw the rectangle, you can also use try/catch methodology as a fail-safe. You can have Flash attempt to draw the rectangle, but if the dimension values are detected to be invalid or out of range, you can throw an error that can be handled programmatically. At that point you can do many things, from simply skipping the action, to substituting default data, to alerting the user to enter valid data.There are two basic parts involved in working with errors in ActionScript: throwing the error and catching the error. There are several errors, which are thrown automatically by the player, such asEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- Chapter 2: Custom Classes
- InhaltsvorschauClasses are absolutely essential to ActionScript 3.0. This is truer in ActionScript 3.0 than in any earlier release of the language. ActionScript 1.0 was essentially a procedural language with modest object-oriented features. ActionScript 2.0 formalized the object-oriented features and took a big step in the direction of a truly object-oriented language. However, ActionScript 3.0 shifts the core focus of ActionScript so that the basic building block is that of the class. If you are using ActionScript 3.0 with Flex, and the introduction of the minor exception of code being placed within
<mx:Script>tags, all ActionScript code must appear within a class. This chapter discusses the fundamentals of writing custom classes in ActionScript 3.0.You want to write a custom class.Save a new file with the .as file extension and the filename matching the name of the class. Then add the class definition to the file with the following structure:package package { public class Class { } }
As noted earlier, the class is the basic building block of all ActionScript 3.0-based applications, so it’s essential that you master the basics of writing a class. For starters, all classes must be placed in .as files, which are plain text files saved with an .as file extension. There can be only one public class definition per .as file, and the name of the file must be the same as the name of the class. For example, if you name a class Example then the definition must be saved in a file called Example.as.In ActionScript 3.0 all classes must be placed in packages. A package is a way of organizing classes into groups, and in ActionScript 3.0 a package is synonymous with a directory on the filesystem. Packages are relative to the classpath (which is discussed in detail in Recipe 2.2), but for this initial discussion the classpath is defined as a path relative to the project (theEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Introduction
- InhaltsvorschauClasses are absolutely essential to ActionScript 3.0. This is truer in ActionScript 3.0 than in any earlier release of the language. ActionScript 1.0 was essentially a procedural language with modest object-oriented features. ActionScript 2.0 formalized the object-oriented features and took a big step in the direction of a truly object-oriented language. However, ActionScript 3.0 shifts the core focus of ActionScript so that the basic building block is that of the class. If you are using ActionScript 3.0 with Flex, and the introduction of the minor exception of code being placed within
<mx:Script>tags, all ActionScript code must appear within a class. This chapter discusses the fundamentals of writing custom classes in ActionScript 3.0.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Creating a Custom Class
- InhaltsvorschauYou want to write a custom class.Save a new file with the .as file extension and the filename matching the name of the class. Then add the class definition to the file with the following structure:
package package { public class Class { } }
As noted earlier, the class is the basic building block of all ActionScript 3.0-based applications, so it’s essential that you master the basics of writing a class. For starters, all classes must be placed in .as files, which are plain text files saved with an .as file extension. There can be only one public class definition per .as file, and the name of the file must be the same as the name of the class. For example, if you name a class Example then the definition must be saved in a file called Example.as.In ActionScript 3.0 all classes must be placed in packages. A package is a way of organizing classes into groups, and in ActionScript 3.0 a package is synonymous with a directory on the filesystem. Packages are relative to the classpath (which is discussed in detail in Recipe 2.2), but for this initial discussion the classpath is defined as a path relative to the project (the .fla file, in the case of Flash or the main class or MXML document in the case of Flex). Therefore, the top-level package is synonymous with the project’s root. The package declaration is always the first thing that appears in a class file; an example syntax follows:package name { }When the class is defined as part of the top-level package, the package name doesn’t need to be specified. In those cases, the package declaration is as follows:package { }When the class file is saved within a subdirectory, the package name corresponds to the relative path of the subdirectory using dots (Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Determining Where to Save a Class
- InhaltsvorschauYou want to determine where to save a class file.Save the file in a directory path corresponding to the package. Then, if necessary, add the top-level directory to the classpath.Class files must always be saved in a directory path that corresponds to the class package. For example, com.examplecorp.net.messaging.email.MessageManager must be saved in com/examplecorp/net/messaging/email/MessageManager.as. The compiler knows to look for classes where the path corresponds to the package. However, the compiler also must know where to look for the top-level directory containing the subdirectories. In the example, the compiler needs to know where the com directory is on the system. The compiler knows where to look because of something called the classpath. The default classpath for any Flex or Flash project includes the project directory. For example, if the com directory is saved in the same directory as the .fla file (Flash) or the main MXML or ActionScript file (Flex), then the compiler will find the classes. However, you may want to save files in a different directory. For example, if you have a common library used by many projects, you may want to save that library in one location rather than making copies for each project. You can add to and edit the classpath so the compiler knows where to look for all your custom classes.For Flash, you can edit the classpath either at the project level or globally. At the project level, select File→Publish Settings, and select the ActionScript Settings button in the Flash tab. For the global classpath, select Edit→Preferences, and click the ActionScript Settings button. Both open a similar dialog that allows you to edit the classpath. You can click the + button to add a new directory to the classpath. For example, if theEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- Creating Properties That Behave As Methods
- InhaltsvorschauYou want to use
publicproperties that behave like methods so you don’t break encapsulation.Use implicit getters and setters.As mentioned in Recipe 2.1, all properties should be declared asprivateorprotected.publicproperties are not a good idea because of a principal called encapsulation. Good encapsulation is something to strive for. It means that a class doesn’t expose its internals in a way that it can be easily broken;publicproperties can enable developers to easily break a class or an instance of a class. Consider the following simple example that uses apublicproperty:package { public class Counter { public var count:uint; public function Counter( ) { count = 0; } } }You can then construct an instance of Counter, and you can change thecountproperty value, as shown here:var counter:Counter = new Counter( ); counter.count++;
However, what if the business rules of the application state that a Counter should never exceed 100? You can see that the Counter class with apubliccount property makes it quite easy to break that rule.One option is to use explicit getters and setters, as in the following example:package { public class Counter { private var _count:uint; public function Counter( ) { _count = 0; } public function getCount( ):uint { return _count; } public function setCount(value:uint):void { if(value < 100) { _count = value; } else { throw Error( ); } } } }Another option is to use implicit getters and setters. Implicit getters and setters are declared as methods, but they look like properties. The syntax for a getter is as follows:public function get
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Creating Static Methods and Properties
- InhaltsvorschauYou want to create methods and properties that are directly accessible from the class rather than from instances of the class.Use the
staticattribute when declaring the property or method.By default, properties and methods are instance properties and methods, which means they are defined for each instance of the class. If the Example class defines a_idproperty and a getId( ) method then, by default, each instance of Example has its own_idproperty and getId( ) method. However, there are cases in which you want the property or method to be associated with the class itself rather than with instances of the class. That means that no matter how many instances of the class there may be, there is just one property or method. Such properties and methods are called static properties and methods.There are examples of static properties and methods in several of the intrinsic Flash Player classes. For example, the Math class defines a round( ) method. The round( ) method is static and is, therefore, accessible directly from the class:trace(Math.round(1.2345));
The Math class consists entirely of static methods and constants. However, a class can have both static and instance methods and/or properties. For example, the String class consists primarily of instance properties and methods. However, the fromCharCode( ) method is declared as static. The fromCharCode( ) method returns a string based on the character codes passed to the method. Since the method isn’t associated with any one String instance, it does not make sense to make the method an instance method. However, it does make sense to declare the method as a static method.You can declare a property or method as static using the static attribute. The static attribute is always used in combination with theEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Creating Subclasses
- InhaltsvorschauYou want to create a class that inherits from an existing class.Write a subclass using the
extendskeyword.There are cases when a new class is a more specific version of an existing class. The new class may feature much of the same behavior as the existing class. Rather than rewriting all the common functionality you can define the new class so it inherits all the functionality of the existing class. In relation to one another, the new class is then called a subclass and the existing class is called a superclass.You can define inheritance between classes in the subclass declaration using theextendskeyword, as follows:public class Subclass extends Superclass
A subclass can reference anypublicorprotectedproperties and methods of the superclass.privateproperties and methods are not accessible outside the class, not even to a subclass.Inheritance is a powerful technique; however, as with anything else, it is important that you use inheritance correctly. Before writing a subclass you need to determine whether or not the new class actually has a subclass relationship with the existing class. There are two basic types of relationships that classes can have: inheritance and composition. You can usually quickly determine the correct relationship between classes by asking whether it’s an “is a” relationship or a “has a” relationship:-
“Is a” relationships are often inheritance relationships. As an example, consider an application that manages a library’s collection.
-
“Has a” relationships are composition relationships in which a class declares a property. Most classes use composition. Oftentimes composition can be implemented in such a way that it achieves the same results as inheritance with greater flexibility (yet generally requiring more code). For example, a book is not an author, but it has an author (or authors).
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Implementing Subclass Versions of Superclass Methods
- InhaltsvorschauYou want to implement a method in a subclass differently than how it was implemented in the superclass.The superclass method must be declared as
publicorprotected. Use theoverrideattribute when declaring the subclass implementation.Often a subclass inherits all superclass methods directly without making any changes to the implementations. In those cases, the method is not redeclared in the subclass. However, there are cases in which a subclass implements a method differently than the superclass. When that occurs, you must override the method. To do that, the method must be declared aspublicorprotectedin the superclass. You can then declare the method in the subclass using theoverrideattribute. As an example, you’ll first define a class, Superclass:package { public class Superclass { public function Superclass( ) {} public function toString( ):String { return "Superclass.toString( )"; } } }Next, define Subclass so it inherits from Superclass:package { public class Subclass extends Superclass { public function Subclass( ) {} } }By default, Subclass inherits the toString( ) method as it’s implemented in Superclass:var example:Subclass = new Subclass( ); trace(example.toString( )); // Displays: Superclass.toString( )
If you want the toString( ) method of Subclass to return a different value, you’ll need to override it in the subclass, as follows:package { public class Subclass extends Superclass { public function Subclass( ) {} override public function toString( ):String { return "Subclass.toString( )"; } } }When overriding a method, it must have exactly the same signature as the superclass. That means the number and type of parameters and the return type of the subclass override must be exactly the same as the superclass. If they aren’t identical, the compiler throws an error.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Creating Constants
- InhaltsvorschauYou want to declare a constant.Declare it just like you would declare a property, except use the
constkeyword in place ofvar.As the name constant implies, constant values do not change. Constants are useful when you have complex values that you want to be able to reference by a simple identifier or when you want to be able to use compile-time error checking for values.Math.PIis an example of a constant that contains a complex value (which is the value of pi, or 3.14159).MouseEvent.MOUSE_UP, which contains the valuemouseUp, is an example of a constant that allows you to use error-checking. When you add an event listener for the mouse up event, you can use the string valuemouseUp. However, if you accidentally have a typo, you won’t be notified of an error, and your code won’t work as expected:// This is valid code, but because of the typo (mousUp instead of mouseUp) the // code won't work as expected. addEventListener("mousUp", onMouseUp);Using a constant helps. If you accidentally misspell the constant, you will receive a compile error that helps you track down the error:// This causes a compile error. addEventListener(MouseEvent.MOUS_UP, onMouseUp);
The syntax for declaring a constant is very similar to that for declaring a standard property. However, rather than using thevarkeyword you use theconstkeyword. Although not required, the majority of constants also happen to be public and static. If you want a constant to be public and static, you must use the correct attributes. Additionally, you must assign a value for a constant when declaring it:static public const EXAMPLE:String = "example";
By convention, constant names are all in uppercase. This convention makes it easy to identify and differentiate constants from properties.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Dispatching Events
- InhaltsvorschauYou want to dispatch events.Extend flash.events.EventDispatcher and call the dispatchEvent( ) method.Events are an important way for objects to communicate. They are essential for creating flexible systems. Flash Player 9, for example, has a built-in event dispatching mechanism in the flash.events.EventDispatcher class. All classes that dispatch events inherit from EventDispatcher (e.g., NetStream and Sprite). If you want to define a class that dispatches events, you can extend EventDispatcher, as follows:
package { import flash.events.EventDispatcher; public class Example extends EventDispatcher { } }The EventDispatcher class has public methods called addEventListener( ) and removeEventListener( ) that you can call from any instance of an EventDispatcher subclass to register event listeners. EventDispatcher also defines a protected method called dispatchEvent( ), which you can call from within a subclass to dispatch an event. The dispatchEvent( ) method requires at least one parameter as a flash.events.Event object or a subclass of Event.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Chapter 3: Runtime Environment
- InhaltsvorschauFlash Player 9 offers a relatively large amount of information about and control over the runtime environment. The flash.system.Capabilities class has many static methods that return information about the player and the computer on which it is running, such as the operating system, language, audio, and video capabilities. There are other classes such as flash.display.Stage and flash.system.Security that allow you to control other elements of the Player such as the right-click menu under Windows (Control-click on the Macintosh) and the Settings dialog box. The flash.display.Stage class also controls the scaling and alignment of the movie within the Player.Perhaps one of the most significant updates to Flash Player 7 within this chapter’s subject matter is the ability to work with the context menu with more detail and precision than was allowed in previous versions of the player. In Flash Player 7, using the ContextMenu class, you can programmatically remove items from the context menu, and perhaps more importantly, you can add items to the menu. And as the name suggests, you can make the context menu so it is actually contextual, so that items in the menu are based on the object on which the menu is being displayed.You want to ensure that the user has the correct version of the Flash Player.Use the Flash Player Detection Kit, available on Adobe’s web site to check the version of player and, if necessary, initiate a player upgrade (http://www.adobe.com/software/flashplayer/download/detection_kit).Detecting the currently installed version of the Flash Player in the user’s browser has been a problem for years, and there have been many solutions used by various developers. They generally fall into three categories:
-
Browser-based script detection
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Introduction
- InhaltsvorschauFlash Player 9 offers a relatively large amount of information about and control over the runtime environment. The flash.system.Capabilities class has many static methods that return information about the player and the computer on which it is running, such as the operating system, language, audio, and video capabilities. There are other classes such as flash.display.Stage and flash.system.Security that allow you to control other elements of the Player such as the right-click menu under Windows (Control-click on the Macintosh) and the Settings dialog box. The flash.display.Stage class also controls the scaling and alignment of the movie within the Player.Perhaps one of the most significant updates to Flash Player 7 within this chapter’s subject matter is the ability to work with the context menu with more detail and precision than was allowed in previous versions of the player. In Flash Player 7, using the ContextMenu class, you can programmatically remove items from the context menu, and perhaps more importantly, you can add items to the menu. And as the name suggests, you can make the context menu so it is actually contextual, so that items in the menu are based on the object on which the menu is being displayed.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- Detecting the Player Version
- InhaltsvorschauYou want to ensure that the user has the correct version of the Flash Player.Use the Flash Player Detection Kit, available on Adobe’s web site to check the version of player and, if necessary, initiate a player upgrade (http://www.adobe.com/software/flashplayer/download/detection_kit).Detecting the currently installed version of the Flash Player in the user’s browser has been a problem for years, and there have been many solutions used by various developers. They generally fall into three categories:
-
Browser-based script detection
-
Server-side detection
-
ActionScript detection
The first method uses JavaScript or VBScript to detect the version of the Flash Player the user has installed. Many of these scripts were prone to errors due to differences in platforms and browser types.Server-side detection can be difficult if you don’t have the ability to create server-side scripts.Most ActionScript-based player detection techniques won’t work directly in an ActionScript 3.0-based .swf. While ActionScript 1.0 and 2.0 had various object methods, variables, and functions that would return the player version, none of those are now valid in an ActionScript 3.0 class. ActionScript 3.0 has its own way of detecting the player version—the flash.system.Capabilities.version property. This, of course, won’t work at all with any version of the Flash Player prior to 8.5, so it is rather useless for Flash detection.Adobe has researched all of these issues thoroughly, and came out with a Flash Player Detection Kit that guides you through the recommended procedures for best detecting the player version.The kit includes documentation on the various issues and potential solutions, including sample VBScript and JavaScript for browser-based detection;Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Detecting the Operating System
- InhaltsvorschauYou want to know the operating system under which the Flash movie is being played, perhaps to indicate which operating systems are not supported or to implement a platform-specific feature.Use the
flash.system.Capabilities.osproperty.In ActionScript 3.0, you can use theflash.system.Capabilities.osproperty, which returns a string indicating the operating system and version name. Possible values include Windows XP, Windows 2000, Windows NT, Windows 98/Me, Windows 95, and Windows CE. On the Macintosh, the string includes the version number, such as Mac OS 9.2.1 or Mac OS X 10.4.4.You can make design choices based on the operating system. For example, your movie might load different assets depending on the user’s operating system. Or, you may simply want to record the operating systems of the users who view your movies for statistical analysis.If all you care about is the general platform type, instead of the specific version, you can check just the first three letters of the string as follows:var os:String = System.capabilities.os.substr(0, 3); if (os == "Win") { // Windows-specific code goes here } else if (os == "Mac") { // Mac-specific code goes here } else { // Must be Unix or Linux }Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Checking the Player Type
- InhaltsvorschauYou want to know what type of Flash Player the .swf is being run from.Use the
flash.system.Capabilities.playerTypeproperty.The different types of Flash Player include:-
Browser plug-in that runs in web browsers such as Mozilla or Firefox
-
ActiveX Control used by Internet Explorer
-
Standalone player, which plays .swfs outside of the browser
-
External player, which is the player integrated in the Flash IDE
There are instances when you need to know which player the .swf is currently being run in. For example, if you are doing any type of integration with browser scripts (e.g., JavaScript, VBScript), it may be important to know whether the application is being run in Internet Explorer or some other type of browser, as these browsers can have different behaviors when running scripts. Indeed, it would be vital to know that the .swf was being run in a standalone player, since JavaScript, etc., would not be available at all in such a case.To check the player type, look at the value offlash.system.Capabilities.playerType. Possible values arePlugIn,ActiveX,StandAlone, andExternal. You could use this in an if statement:if(flash.system.Capabilities.playerType == "Plugin") { // do actions for Mozilla, etc. browsers } else if(flash.system.Capabilities.playerType == "ActiveX") { // do actions for IE } else { // do actions for no browser }Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Checking the System Language
- InhaltsvorschauYou want to know what language is used on the computer viewing the movie and how the user will input text.Use the
flash.system.Capabilities.languageproperty and theflash.system.IMEclass.You can use theflash.system.Capabilities.languageproperty to determine the language that is used on the computer on which the movie is being played. The property returns a two-letter ISO-639-1 language code (e.g., “fr” for French). Where applicable, a two-letter country code is appended, separated from the country code with a hyphen (e.g., “zh-CN” for Simplified Chinese and “zh-TW” for Traditional Chinese).For a summary of language codes, see http://lcweb.loc.gov/standards/iso639-2/englangn.htmlandhttp://www.iso.org/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html.Here is an example of how to use thelanguageproperty:// Example output: en-US trace(flash.system.Capabilities.language);
You can use this property to dynamically load content in the appropriate language:// Create an associative array with language codes for the keys // and greetings for the values. var greetings:Array = new Array( ); greetings["en"] = "Hello"; greetings["es"] = "Hola"; greetings["fr"] = "Bonjour"; // Extract the first two characters from the language code. var lang:String = flash.system.Capabilities.language.substr(0, 2); // Use a default language if the language is not in the list if (greetings[lang] == undefined) { lang = "en"; } // Display the greeting in the appropriate language. trace(greetings[lang]);When you want to offer multiple language capabilities in your movies, you can choose from several different approaches. One, as shown in the preceding code, is to create associative arrays for all the text that appears in the movie. Another approach is to create static content in multiple movies (one for each language) and to load those movies based on the language code. With this technique, eachEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Detecting Display Settings
- InhaltsvorschauYou want to know the display settings for the device on which the movie is being played.Use the
screenResolutionXandscreenResolutionYproperties of thesystem.capabilitiesobject.You should use theflash.system.Capabilitiesobject to determine the display settings of the device that is playing the movie. ThescreenResolutionXandscreenResolutionYproperties return the display resolution in pixels.// Example output: // 1024 // 768 trace(flash.system.Capabilities.screenResolutionX); trace(flash.system.Capabilities.screenResolutionY);
You can use these values to determine how to display a movie, or even which movie to load. These decisions are increasingly important as more handheld devices support the Flash Player. For example, the dimensions of a cellphone screen and a typical desktop computer display are different, so you should load different content based on the playback device.var resX:int = flash.system.Capabilities.screenResolutionX; var resY:int = flash.system.Capabilities.screenResolutionY; // If the resolution is 240 x 320 or less, then load the PocketPC // movie version. Otherwise, assume the device is a desktop computer // and load the regular content. if ( (resX <= 240) && (resY <= 320) ) { var url:String = "main_pocketPC.swf"; } else { var url:String = "main_desktop.swf"; } loader.load(new URLRequest(url));You can also use the screen resolution values to center a pop-up browser window:var resX:int = flash.system.Capabilities.screenResolutionX; var resY:int = flash.system.Capabilities.screenResolutionY; // Set variables for the width and height of the new browser window. var winW:int = 200; var winH:int = 200; // Determine the X and Y values to center the window. var winX:int = (resX / 2) - (winW / 2); var winY:int = (resY / 2) - (winH / 2); // Create the code that, when passed to URLLoader.load( ) // opens the new browser window. var jsCode:String = "javascript:void( newWin=window.open('http://www.person13.com/'," + "'newWindow', 'width=" + winW + ", height=" + winH + "," + "left=" + winX + ",top=" + winY + "'));"; // Call the JavaScript function using a URLLoader object urlLoader.load(new URLRequest(jsCode));Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Scaling the Movie
- InhaltsvorschauYou want to control the way in which a movie fits in the Player, including the scaling.Use the
stage.scaleModeproperty.There are several different scale modes that control how a movie is scaled when the player changes size. The modes are defined as the following strings: exactFit, noBorder, noScale, and showAll. However, to avoid typographical errors, these strings have also been defined in theflash.display.StageScaleModeclass as the static properties:EXACT_FIT,NO_BORDER,NO_SCALE, andSHOW_ALL.The Flash Player defaults to a scale mode of showAll. In this mode, the Flash movie scales to fit the player’s size while maintaining the movie’s original aspect ratio. The result is that the movie can potentially have borders on the sides if the Player’s aspect ratio does not match the movie’s aspect ratio. You can set a movie to showAll mode from your main application class as follows (don’t forget to import theflash.display.StageScaleModeclass):stage.scaleMode = StageScaleMode.SHOW_ALL;
Note thatstageis not a global object, but a property of any display object, so this statement only works in a sprite or other class that extends theDisplayObjectclass.The noBorder mode scales a movie to fit the Player while maintaining the original aspect ratio; however, it forces the Player to display no borders around the Stage. If the aspect ratio of the Player does not match that of the movie, some of the movie will be cut off on the sides. You can set a movie to noBorder mode as follows:stage.scaleMode = StageScaleMode.NO_BORDER;
The exactFit mode scales a movie to fit the Player, and it alters the movie’s aspect ratio, if necessary, to match that of the Player. The result is that the movie always fills the Player exactly, but the elements of the movie may be distorted. For example:Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Changing the Alignment
- InhaltsvorschauYou want to change the alignment of the movie within the Player.Use the
stage.alignproperty.Flash movies appear in the center of the Player by default. You can control the alignment of a movie within the Player by setting thestage.alignproperty of any class that extendsDisplayObject. The various alignment modes are implemented as strings, such as “T” for “top,” “L” for “left,” etc. However, to avoid errors in typing, these have also been made properties of theflash.display.StageAlignclass, listed in Table 3-1.Table : Alignment as controlled by stage.align Value Vertical alignment Horizontal StageAlign.TOP
Top Center StageAlign.BOTTOM
Bottom Center StageAlign.LEFT
Center Left StageAlign.RIGHT
Center Right StageAlign.TOP_LEFT
Top Left StageAlign.TOP_RIGHT
Top Right StageAlign.BOTTOM_LEFT
Bottom Left StageAlign.BOTTOM_RIGHT
Bottom Right There is no “official” value to center the Stage both vertically and horizontally in the Player. Of course, if this is what you want, you don’t have to do anything since that is the default mode. But if you have changed to one of the other modes and want to go back to centered alignment, any string that doesn’t match one of the other modes will center the Stage. The easiest and safest would be an empty string,"".The following class demonstrates the effects of both the scale mode and alignment of a movie within the player. Experiment by changing thestage.scaleModeandstage.alignproperties to their different values and scaling the browser to various sizes.package { import flash.display.Sprite; import flash.display.StageScaleMode; import flash.display.StageAlign; public class ExampleApplication extends Sprite { public function ExampleApplication( ) { stage.scaleMode = StageScaleMode.NO_SCALE; stage.align = StageAlign.TOP_RIGHT; graphics.beginFill(0xff0000); graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight); graphics.endFill( ); } } }Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Hiding the Flash Player’s Menu Items
- InhaltsvorschauYou want to hide the right-click menu under Windows (Control-click on the Mac).You can’t disable the Flash Player’s pop-up menu entirely, but you can minimize the options shown in the menu by setting the
stage.showDefaultContextMenuproperty tofalse.By default, the following options appear in the Flash Player’s pop-up menu when the user right-clicks in Windows (or Control-clicks on the Mac):-
Zoom In
-
Zoom Out
-
Show All
-
Quality (Low, Medium, or High)
-
Settings
-
Print
-
Show Redraw Regions (if using a debug player)
-
Debugger (if using a debug player)
-
About Adobe Flash Player 9
You can remove many of the options with the following line of ActionScript code, although the Settings and About and debug player options remain in place:stage.showDefaultContextMenu = false;
Unfortunately, Flash does not provide any way to disable the menu entirely. Furthermore, Windows users are accustomed to using right-click to display a pop-up browser menu that allows them to open a link in a new window, for example. Such options are not available due to the Flash pop-up menu’s presence.See Recipe 3.11 for a way to display Flash’s Settings dialog box without requiring the user to right-click (in Windows) or Control-click (on Mac).Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Detecting the Device’s Audio Capabilities
- InhaltsvorschauYou want to determine the audio capabilities of the device on which the Flash Player is running.Use the
hasAudioandhasMP3properties of the flash.system.Capabilities class.Theflash.system.Capabilities.hasAudioproperty returnstrueif the user’s system has audio capabilities andfalseotherwise. This is extremely important for playing movies on multiple devices. If a device has no audio support, you want to avoid forcing users to download something they cannot hear (especially because audio can be quite large).// Load a .swf containing sound only if the Player can play audio if (flash.system.Capabilities.hasAudio) { content = "sound.swf"; } else { content = "silent.swf"; } // code to load the .swf referenced in contentJust because a system has audio capabilities, however, does not necessarily mean that it can play back MP3 sounds. Therefore, if publishing MP3 content, you should test for MP3 capabilities using theflash.system.Capabilities.hasMP3property. MP3 sounds are preferable, if supported, because they offer better sound quality to file size ratios than ADCP sounds.// If the Player can play MP3s, load an MP3 using a Sound object. // Otherwise, load a .swf containing ADCP sound into a nested // sprite. if (flash.system.Capabilities.hasMP3) { var url:URLRequest = new URLRequest("sound.mp3”); sound = new Sound(url); sound.play( ); } else { // code to load an external .swf containing a ADCP sound }
It is important to understand that thehasAudioandhasMP3property settings are based on the capabilities of the Player and not of the system on which the Player is running. The desktop system players (for Windows, Mac OS, and Linux) always returntruefor both properties regardless of whether or not the system actually has the hardware (i.e., soundcard and speakers) to play back sounds. However, players for other devices may returnEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Detecting the Device’s Video Capabilities
- InhaltsvorschauYou want to determine the video capabilities of the device on which the Flash Player is running.Use the
hasEmbeddedVideo,hasStreamingVideo, andhasVideoEncoderproperties of theflash.system.Capabilitiesclass.Before you attempt to deliver video content to a user, it is important to check whether his system is capable of playing video, and how it should be delivered. The most efficient way to deliver Flash video is to stream it to the player. This allows the user to view the video as it is coming in, rather than waiting until the entire (often quite large) file has downloaded. However, the user’s system may not be capable of receiving streaming video. To check this, use theflash.system.Capabilities.hasStreamingVideoproperty. If this returnsfalse, one option is to have the player load another .swf that contains an embedded video. However, before doing this, you should check the propertyflash.system.Capabilities.hasEmbeddedVideoto ensure that the user can view this content before initiating this download. Your code would look something like this:if(flash.system.Capabilities.hasStreamingVideo) { // Code to set up a video stream and start streaming a // specific video } else if(flash.system.Capabilities.hasEmbeddedVideo) { // Code to load an external .swf containing an embedded video } else { // Alternate content without any video }Similarly, if your application requires video stream encoding, such as the use of a web cam to transmit live video from the user’s system, you want to ensure that the system is capable of doing such encoding. You can test this with theflash.system.Capabilities.hasVideoEncoderproperty. Like the earlier example, you would probably test this property in an if statement and set up the video streaming only if it testedtrue. Otherwise, you could display a message to the user explaining the situation or redirect him to another page.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Prompting the User to Change Player Settings
- InhaltsvorschauYou want to open the user’s Flash Player Settings dialog box to prompt her to allow greater access to her local system.Use the flash.system.Security.showSettings( ) method.The flash.system.Security.showSettings( ) method opens the Flash Player Settings dialog box, which includes several tabs. You’ll pass a string as a parameter to indicate which tab you want it to open. These strings have been made static properties of the flash.system.SecurityPanel class, to avoid typographical errors. The possible values are:
- SecurityPanel.CAMERA
-
Allows the user to select a camera to use.
- SecurityPanel.DEFAULT
-
Shows whichever tab was opened the last time the Security Panel was open.
- SecurityPanel.LOCAL_STORAGE
-
Allows the user to specify how local shared objects are stored, including the maximum allowable disk usage.
- SecurityPanel.MICROPHONE
-
Allows the user to select a microphone and adjust the volume.
- SecurityPanel.PRIVACY
-
Allows the user to specify whether to allow Flash access to her camera and microphone.
- SecurityPanel.SETTINGS_MANAGER
-
Opens a new browser window and loads the Settings Manager page, which gives the user several more detailed options and the ability to make global changes, rather than just to the domain of the specific movie that is active.
If you don’t pass any parameters to the showSettings( ) method, it uses SecurityPanel.DEFAULTEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Dealing with System Security
- InhaltsvorschauYou want to load a .swf from another domain into your application and allow it to have access to the ActionScript in the application.Use one of the following: flash.system.Security.allowDomain( ), flash.system.Security.allowInsecureDomain( ), or a policy file.In many cases, all of the .swfs in a multi-.swf application would live on the same server (thus the same domain). There may be cases, however, when your application needs to load in an external .swf from another domain. In such a case, neither the .swf nor the loading application would be able to access the other’s code. You can allow such access by using flash.system.Security.allowDomain( ), flash.system.Security.allowInsecureDomain( ), or a policy file.The .swf that is going to be accessed must explicitly allow access by .swfs in the other domain. It does not matter which .swf is loading or being loaded. To clarify, call the .swf being accessed, accessed.swf, and the .swf doing the access, accessing.swf. Say accessing.swf lives on mydomain.com and loads in accessed.swf from otherdomain.com, into an object named content (see Figure 3-1).Now, accessing.swf tries to access a variable called
authorNamefrom the loaded accessed.swf. At this point, accessed.swf complains and won’t allow access by a .swf from another domain.To overcome this, accessed.swf needs the following line:flash.system.Security.allowDomain("http://mydomain.com");This lets it know that it is alright to allow access by any .swf from that domain.You should note that the permission is one-way. If the loaded .swf now needs access to some code in the .swf that loaded it, it would not be able to get at that code. In this case, the loading .swf would explicitly need to allow access toEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Chapter 4: Numbers and Math
- InhaltsvorschauAlthough numbers aren’t always in the spotlight, don’t overlook their power and importance in your code. Numbers come in all shapes and sizes—from binary to decimal to hexadecimal. Each type of representation has its own particular niche in which it is most valuable. For example, hexadecimal numbers are often used to represent RGB color values because they make it easy to discern each of the three color components. (See Recipe 4.2 to learn how to convert between different number bases.)Closely related to numbers is the subject of mathematics. Without mathematical operations, your Flash movies would be rather dull. Simple operations such as addition and subtraction are essential to even the most basic ActionScript applications, and more advanced math, such as random number generation and trigonometric calculations, is equally essential to advanced applications.ActionScript 3.0 has three basic numeric types: number, int, and uint. number is for any floating-point numbers, whereas int and uint are for integers (whole numbers). The distinction between int and uint is that int is the set of negative and non-negative integers, while uint is the set of non-negative integers (unsigned integers).You want to specify a value in binary, octal, or hexadecimal.Hexadecimal literals start with
0x(where the first character is a zero, not an “oh”), and octal literals start with0(again, zero, not “oh”). Binary numbers can’t be represented directly, but you can either specify their octal or hexadecimal equivalent or use the parseInt( ) function to convert a string to a number.You can represent numbers in ActionScript using whichever format is most convenient, such as decimal or hexadecimal notation. For example, if you set the value of theSprite.rotationEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Introduction
- InhaltsvorschauAlthough numbers aren’t always in the spotlight, don’t overlook their power and importance in your code. Numbers come in all shapes and sizes—from binary to decimal to hexadecimal. Each type of representation has its own particular niche in which it is most valuable. For example, hexadecimal numbers are often used to represent RGB color values because they make it easy to discern each of the three color components. (See Recipe 4.2 to learn how to convert between different number bases.)Closely related to numbers is the subject of mathematics. Without mathematical operations, your Flash movies would be rather dull. Simple operations such as addition and subtraction are essential to even the most basic ActionScript applications, and more advanced math, such as random number generation and trigonometric calculations, is equally essential to advanced applications.ActionScript 3.0 has three basic numeric types: number, int, and uint. number is for any floating-point numbers, whereas int and uint are for integers (whole numbers). The distinction between int and uint is that int is the set of negative and non-negative integers, while uint is the set of non-negative integers (unsigned integers).Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- Representing Numbers in Different Bases
- InhaltsvorschauYou want to specify a value in binary, octal, or hexadecimal.Hexadecimal literals start with
0x(where the first character is a zero, not an “oh”), and octal literals start with0(again, zero, not “oh”). Binary numbers can’t be represented directly, but you can either specify their octal or hexadecimal equivalent or use the parseInt( ) function to convert a string to a number.You can represent numbers in ActionScript using whichever format is most convenient, such as decimal or hexadecimal notation. For example, if you set the value of theSprite.rotationproperty, it is most convenient to use a decimal number:rectangleSprite.rotation = 180;
On the other hand, hexadecimal numbers are useful for specifying RGB colors. For example, you can set thergbvalue for a ColorTransform object in hexadecimal notation (in this example,0xF612ABis a hex number representing a shade of pink):var pink:ColorTransform = new ColorTransform( ); pink.rgb = 0xF612AB;
Any numeric literal starting with0Xor0x(where the first character is a zero, not an “oh”) is presumed to be a hexadecimal number (i.e., hex or base-16). Allowable digits in a hexadecimal number are 0 through 9 and A through F (upper- and lowercase letters are equivalent, meaning0xFFis the same as0xff).Any numeric literal starting with0(again, zero not “oh”), but not0xor0X, is presumed to be an octal number (i.e., base-8). Allowable digits in an octal number are 0 through 7; for example,0777is an octal number. Most developers don’t ever use octal numbers in ActionScript. For most developers it’s simply far more convenient to represent most numbers as decimal numbers (base-10), except color values for which it is generally more convenient to use hexadecimal representation. There aren’t many common examples for which octal representation is more convenient than decimal or hexadecimal.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Converting Between Different Number Systems
- InhaltsvorschauYou want to convert a number between different bases (such as decimal, binary, hexadecimal, etc.).Use the parseInt( ) function with the radix parameter (the radix is the number’s base) to convert a string to a decimal representation. Use the toString( ) method of a Number, uint, or int object with the radix parameter to convert a decimal number to a string representation of the value in another base.No matter how you set a number value in ActionScript, the result is always retrieved as a decimal (base-10) number:
// Create a Color object var pink:ColorTransform = new ColorTransform( ); // Set the RGB value as a hexadecimal pink.rgb = 0xF612AB; // This displays the value as decimal: 16126635 trace(pink.rgb);However, if you want to output a value in a different base, you can use toString( radix ) for a Number, uint, or int object to convert any number value to a string representing that number in the specified base.These two examples convert numeric literals to uint objects and output the string representations in base-2 (binary) and base-16 (hexadecimal) format.// The radix is 2, so output as binary trace(new uint(51).toString(2)); // Displays: 110011 // The radix is 16, so output as hex trace(new uint(25).toString(16)); // Displays: 19
When using the toString( ) method with a variable that contains a numeric literal value, Flash automatically creates a new Number, uint, or int object before calling the toString( ) method. Although it’s not typically the best practice, it is not technically wrong, and in most applications the differences are negligible. This example assigns a primitive number to a variable and calls the toString( ) method to output the value in hexadecimal:var quantity:Number = 164; trace(quantity.toString(16)); // Displays: a4
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Rounding Numbers
- InhaltsvorschauYou want to round a number to the nearest integer, decimal place, or interval (such as to the nearest multiple of five).Use Math.round( ) to round a number to the nearest integer. Use Math.floor( ) and Math.ceil( ) to round a number down or up. Use a custom NumberUtilities.round( ) method to round a number to a specified number of decimal places or to a specified multiple.There are numerous reasons to round numbers. For example, when displaying the results of a calculation, you might display only the intended precision. Because all arithmetic in ActionScript is performed with floating-point numbers, some calculations result in unexpected floating-point numbers that must be rounded. For example, the result of a calculation may be 3.9999999 in practice, even though it should be 4.0 in theory.The Math.round( ) method returns the nearest integer value of any parameter passed to it:
trace(Math.round(204.499)); // Displays: 204 trace(Math.round(401.5)); // Displays: 402
The Math.floor( ) method rounds down, and the Math.ceil( ) method rounds up:trace(Math.floor(204.99)); // Displays: 204 trace(Math.ceil(401.01)); // Displays: 402
To round a number to the nearest decimal place:-
Decide the number of decimal places to which you want the number rounded. For example, if you want to round 90.337 to 90.34, then you want to round to two decimal places, which means you want to round to the nearest .01.
-
Divide the input value by the number chosen in Step 1 (in this case, .01).
-
Use Math.round( ) to round the calculated value from Step 2 to the nearest integer.
-
Multiple the result of Step 3 by the same value that you used to divide in Step 2.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Inserting Leading or Trailing Zeros or Spaces
- InhaltsvorschauYou want to add leading or trailing zeros or spaces to a number to display it as a string.Use the custom NumberFormat class, apply a mask, and then call the format( ) method.You might need to format numbers with leading or trailing zeros or spaces for display purposes, such as when displaying times or dates. For example, you would want to format 6 hours and 3 minutes as 6:03 or 06:03, not 6:3. Additionally, sometimes you’ll want to apply leading and/or trailing spaces to align the columns of several numbers; for example:
123456789 1234567 12345Although you can certainly work out the algorithms on your own to add leading or trailing characters, you’ll likely find working with a NumberFormat object much faster, simpler, and more flexible. The NumberFormat class is a custom class included with the downloads for this book at http://www.rightactionscript.com/ascb. That class is part of the ascb.util package, so the first thing you’ll want to do is make sure you have an import statement:import ascb.util.NumberFormat;
Next you need to determine the mask that you’ll use to format the number. The mask can consist of zeros (0), pound signs (#), dots (.), and commas (,); any other characters are disregarded.- Zeros (
0) -
Placeholders that are either filled with the corresponding digit or a zero.
- Pound signs (
#) -
Placeholders that are either filled with the corresponding digit or a space.
- Dots (
.) -
Decimal point placeholders; they can be replaced by the localized decimal point symbol.
- Commas (
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Zeros (
- Formatting Numbers for Display Without a Mask
- InhaltsvorschauYou want to format a number for display without using a mask.Create a NumberFormat object with no mask setting, then call the format( ) method.Recipe 4.4 discusses complex ways to format numbers as strings, including using masks and applying leading and trailing zeros and spaces. Sometimes, however, you just want to format a number without those complexities. The NumberFormat class provides that simplicity as well. If no mask is applied to a NumberFormat object, then the format( ) method applies basic, localized formatting to a number, as shown in the following example:
var styler:NumberFormat = new NumberFormat( ); trace(styler.format(12.3)); trace(styler.format(123.4)); trace(styler.format(1234.5)); trace(styler.format(12345.6));
Notice that a mask wasn’t applied to the NumberFormat object at any point. Assuming U.S.-style formatting, the preceding code outputs the following:12.3 123.4 1,234.5 12,345.6
As with the other use of the format( ) method (discussed in Recipe 4.4), this usage attempts to use automatic localization detection. However, the same issues may be applicable. You may prefer to override the automatic localization settings, and you can accomplish that by using the same techniques discussed in Recipe 4.4, as illustrated with the following example:var styler:NumberFormat = new NumberFormat( ); Locale.slanguage = "fr"; trace(styler.format(1234, new Locale("en"))); trace(styler.format(12345, {group: ":", decimal: "|"})); trace(styler.format(123456));The output from the preceding code is as follows:1,234 12:345 123.456
Recipes 4.3 and 4.4 can be used to ensure a certain number of digits are displayed past the decimal point. Then aligning numbers is simply a matter of setting the text field’s format to right justification using theEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Formatting Currency Amounts
- InhaltsvorschauYou want to format a number as currency, such as dollars.Use the NumberFormat.currencyFormat( ) method.Unlike some other languages, such as ColdFusion, ActionScript does not have a built-in function for formatting numbers as currency amounts. However, the custom NumberFormat class includes a currencyFormat( ) method that takes care of basic currency formatting for you.The currencyFormat( ) method requires at least one parameter; the number you want to format as currency. The following example illustrates the simplest use of currencyFormat( ):
var styler:NumberFormat = new NumberFormat( ); trace(styler.currencyFormat(123456));
Assuming that the preceding code is run on a U.S. English computer, the output is as follows:$123,456.00
As with the format( ) method of the NumberFormat class discussed in Recipes 4.4 and 4.5, the currencyFormat( ) method uses automatic localization detection settings. Therefore, if the preceding code is run on a computer in Spain running a Spanish operating system, the output is as follows:123.456,00
However, the Locale class (which is responsible for determining the locale from where the application is being run) may not be able to correctly detect the locale. Furthermore, you may simply want to override automatic localization so you get a consistent value regardless of where the application is run. There are several ways you can override the automatic localization detection; the same ways that you can override the localization settings when using the format( ) method:-
Use a Locale object as the second parameter when calling currencyFormat( ).
-
Assign global values to the Locale.slanguage and/or Locale.svariant
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Generating a Random Number
- InhaltsvorschauYou want to use ActionScript to generate a random number.Use Math.random( ) to generate a random number between 0 and .999999. Optionally, use the NumberUtilities.random( ) method to generate a random number within a specific range.You can use the Math.random( ) method to generate a random floating-point number from 0 to 0.999999999. In most cases, however, programs call for a random integer, not a random floating-point number. Furthermore, you may want a random value within a specific range. If you do want a random floating-point number, you’ll need to specify its precision (the number of decimal places).The simplest way to generate random numbers within a range and to a specified precision is to use the custom NumberUtilities.random( ) method. This method accepts up to three parameters, described as follows:
minimum-
The smallest value in the range specified as a Number.
maximum-
The largest value in the range specified as a Number.
roundToInterval-
The optional interval to use for rounding. If omitted, numbers are rounded to the nearest integer. You can specify integer intervals to round to integer multiples. You can also specify numbers smaller than 1 to round to numbers with decimal places.
The NumberUtilities class is in the ascb.util package, so be sure to include animportstatement.The following example illustrates some uses of the round( ) method:// Generate a random integer from 0 to 100. trace(NumberUtilities.random(0, 100)); // Generate a random multiple of 5 from 0 to 100. trace(NumberUtilities.random(0, 100, 5)); // Generate a random number from -10 to 10, rounded to the // nearest tenth. trace(NumberUtilities.random(-10, 10, .1)); // Generate a random number from -1 to 1, rounded to the // nearest five-hundredth. trace(NumberUtilities.random(-1, 1, .05));
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Simulating a Coin Toss
- InhaltsvorschauYou want to simulate tossing a coin or some other Boolean (
true/false) event in which you expect a 50 percent chance of either outcome.Use the NumberUtilities.random( ) method to generate an integer that is either 0 or 1, and then correlate each possible answer with one of the desired results.You can use the random( ) method from Recipe 4.7 to generate a random integer in the specified range. To relate this result to an event that has two possible states, such as a coin toss (headsortails) or a Boolean condition (trueorfalse), treat each random integer as representing one of the possible states. By convention, programmers use 0 to represent one state (such as “off”) and 1 to represent the opposite state (such as “on”), although you can use 1 and 2 if you prefer. For example, here’s how you could simulate a coin toss:package { import flash.display.Sprite; import flash.text.TextField; import flash.events.MouseEvent; import ascb.util.NumberUtilities; public class CoinExample extends Sprite { private var _field:TextField; public function CoinExample( ) { _field = new TextField( ); _field.autoSize = "left"; addChild(_field); var circle:Sprite = new Sprite( ); circle.graphics.beginFill(0, 100); circle.graphics.drawCircle(100, 100, 100); circle.graphics.endFill( ); circle.addEventListener(MouseEvent.CLICK, onClick); addChild(circle); } private function onClick(event:MouseEvent):void { var randomNumber:Number = NumberUtilities.random(0, 1); _field.text = (randomNumber == 0) ? "heads" : "tails"; } } }In the following example, a function is used to test the coinFlip( ) routine to see if it is reasonably evenhanded. Do you expect a perfect 50/50 distribution regardless of the number of coin tosses? Test it and see.package { import flash.display.Sprite; import flash.text.TextField; import ascb.util.NumberUtilities; public class CoinTest extends Sprite { private var _field:TextField; public function CoinTest( ) { _field = new TextField( ); _field.autoSize = "left"; addChild(_field); var heads:Number = 0; var tails:Number = 0; var randomNumber:Number; for(var i:Number = 0; i < 10000; i++) { randomNumber = NumberUtilities.random(0, 1); if(randomNumber == 0) { heads++; } else { tails++; } } _field.text = "heads: " + heads + ", tails: " + tails; } } }Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Simulating Dice
- InhaltsvorschauYou want to mimic rolling dice.Use the NumberUtilities.random( ) method to generate random numbers in the desired range.You can use the random( ) method from Recipe 4.7 to generate random integer values to simulate rolling a die or dice in your Flash movies. Mimicking the rolling of dice is an important feature in many games you might create using ActionScript, and the random( ) method makes your job easy.NumberUtilities.random(1, 12) does not correctly simulate a pair of six-sided dice because the results must be between 2 and 12, not 1 and 12. Does NumberUtilities.random(2, 12) give the correct result? No, it does not. NumberUtilities.random(2, 12) results in a smooth distribution of numbers from 2 to 12, whereas in games played with two dice, 7 is much more common than 2 or 12. Therefore, you must simulate each die separately and then add the result together. Furthermore, in many games, such as backgammon, game play depends on the individual value of each die, not simply the total of both dice, so you’ll want to keep them separate.It is not uncommon to want to generate a random number and then store it for later use. If you want to reuse an existing random number, be sure to save the result rather than generating a new random number. Note the difference in these two scenarios. In the first scenario,
dicealways is the sum ofdie1plusdie2:var die1:uint = NumberUtilities.random(1, 6); var die2:uint = NumberUtilities.random(1, 6); var dice:uint = die1 + die2;
In the following scenario, there is no relation between the value ofdiceand the earlier random values stored indie1anddie2. In other words, even ifdie1anddie2add up to 7,dicestores a completely different value between 2 and 12:Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Simulating Playing Cards
- InhaltsvorschauYou want to use ActionScript to deal cards for a card game using a standard 52-card deck (without Jokers).Use the custom Cards class.Playing cards requires a greater degree of sophistication than, say, rolling a couple dice. Therefore, to work with playing cards within your Flash applications, you should use a custom Cards class.The Cards class is in the ascb.play package, and therefore you should be sure to import the class before you try to use it in your code.
import ascb.play.Cards;
You can create a new Cards object using the constructor as follows:var cards:Cards = new Cards( );
By default, a Cards object creates a standard deck of 52 playing cards. Next you need to deal the cards by using the deal( ) method. The deal( ) method returns an array of CardHand objects. You should specify at least one parameter when calling the deal( ) method; the number of hands to deal.// Deal four hands. var hands:Array = cards.deal(4);
By default, the deal( ) method deals every card in the deck (except when 52 is not evenly divisible by the number of hands). Some card games, such as Euchre, require fewer cards in each hand with some cards remaining in the deck. You can, therefore, specify a second, optional parameter that determines the number of cards per hand:// Deal four hands with five cards each. var hands:Array = cards.deal(4, 5);
Each CardHand object is an array of Card objects. The CardHand class also provides an interface to draw and discard cards from the deck from which the hand was originally dealt. You can use the discard( ) method by specifying a list of card indices as parameters. The cards then are removed from the hand and added back to the bottom of the deck:Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Generating a Unique Number
- InhaltsvorschauYou want to generate a unique number, such as a number to append to a URL to prevent caching of the URL.Use the NumberUtilities.getUnique( ) method.Unique numbers are most commonly used to generate a unique URL (to prevent it from being cached). That is, by appending a unique number to the end of a URL, it is unlike any previous URL; therefore, the browser obtains the data from the remote server instead of the local cache.The NumberUtilities.getUnique( ) method returns a number based on the current epoch milliseconds. (The following example assumes you’ve imported ascb.util.NumberUtilities.)
// Display a unique number. trace(NumberUtilities.getUnique( ));
In most circumstances the preceding code returns the current epoch in milliseconds. However, it is possible that you may want to generate a set of unique numbers in less than a millisecond of processing time. In that case, you’ll find that the getUnique( ) method adds a random number to the epoch milliseconds to ensure a unique number. The following example generates more than one number within the same millisecond:for(var i:Number = 0; i < 100; i++) { trace(NumberUtilities.getUnique( )); }Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Converting Angle Measurements
- InhaltsvorschauYou want to work with angle values in ActionScript, but you must convert to the proper units.Use the Unit and Converter classes.The
_rotationproperty of a movie clip object is measured in degrees. Every other angle measurement in ActionScript, however, uses radians, not degrees. This can be a problem in two ways. First, if you want to set the_rotationproperty based on the output of one of ActionScript’s trigonometric methods, you must convert the value from radians to degrees. Second, humans generally prefer to work in degrees, which we must convert to radians before feeding to any of the trigonometric methods. Fortunately, the conversion between radians and degrees is simple. To convert from radians to degrees, you need only to multiply by 180/Math.PI. Likewise, to convert from degrees to radians you need only to multiply by the inverse: Math.PI/180. However, you may find it more convenient to simply use the custom Unit and Converter classes.The Unit and Converter classes are two custom classes found in the ascb.unit package that facilitate conversions between various units of measurement, including degrees, radians, and gradians (there are 400 gradians in a complete circle). The first step is to create a Unit instance that describes the type of unit from which you want to convert. The Unit class provides a large group of constants that make it very convenient. TheUnit.DEGREE,Unit.RADIAN, andUnit.GRADIANconstants return new Unit objects that represent degrees, radians, and gradians, respectively. Unit objects have a handful of properties, includingname,category,label, andlabelPlural:var degree:Unit = Unit.DEGREE; trace(degree.name); // Displays: degree trace(degree.category); // Displays: angle trace(degree.label); // Displays: degree trace(degree.labelPlural); // Displays: degrees
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Calculating the Distance Between Two Points
- InhaltsvorschauYou want to calculate the distance between two points.Use Math.pow( ) and Math.sqrt( ) in conjunction with the Pythagorean theorem.You can calculate the distance (in a straight line) from any two points by using the Pythagorean Theorem. The Pythagorean Theorem states that in any right triangle (a triangle in which one of the angles is 90 degrees) the length of the hypotenuse (the long side) is equal to the square root of the sum of the squares of the two other sides (referred to as the legs of the triangle). The Pythagorean theorem is written as:
a2 + b2 = c2You can use this formula to calculate the distance between any two points, where a is the difference between the points’ X coordinates, b is the difference between their Y coordinates, and c (the distance to be determined) equals the square root of (a 2 + b 2). In ActionScript, this is written as:var c:Number = Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2));
How do you calculate the distance between two points using a right triangle? Although it might not seem immediately obvious, you can form an imaginary right triangle using any two points in the Flash coordinate system, as shown in Figure 4-1.
Figure 4-1: The hypotenuse of a right triangle is drawn between two points to calculate the distance between the pointsThe hypotenuse of the imaginary triangle is formed by the line connecting the two points. The legs of the triangle are formed by lines extending horizontally and vertically from the two points. You can find the lengths of the legs by finding the differences between the X and Y coordinates. The length of leg a is determined by the difference in the points’ X coordinates, and the length of legEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Determining Points Along a Circle
- InhaltsvorschauYou want to calculate the coordinates of a point along a circle, given the circle’s radius and the sweep angle.Use the Math.sin( ) and Math.cos( ) methods to calculate the coordinates using basic trigonometric ratios.Finding the coordinates of a point along a circle is easy with some trigonometry. So let’s look at the formulas you can use within your ActionScript code and the theory behind them.Given any point on the Stage—a point we’ll call p0, with coordinates (x0, y0)—plus a distance and the angle from the horizontal, you can find the coordinates of another point—which we’ll call p1, with coordinates (x1, y1)—using some basic trigonometric ratios. The angle is formed between a conceptual line from p0 to p1 and a line parallel to the X axis, as shown in Figure 4-2. The opposite side is the side furthest away from the angle. The adjacent side is the side that forms the angle with the help of the hypotenuse.
Figure 4-2: The angle, adjacent side, opposite side, and hypotenuse of a right triangleIf you know the distance between two points and the angle to the horizontal, as shown in Figure 4-2, you can calculate the X and Y coordinates of the destination point using trigonometric functions. The trigonometric sine of the angle is equal to the ratio of the opposite side over the hypotenuse, like so:sine(angle) = opposite/hypotenuse
Solving for the opposite side’s length, this can be written as:opposite = sine(angle) * hypotenuse
As you can see in Figure 4-2, the opposite side represents the change in the Y direction.The trigonometric cosine of the angle is equal to the ratio of the adjacent side over the hypotenuse, like so:Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Converting Between Units of Measurement
- InhaltsvorschauYou want to convert between Fahrenheit and Celsius, pounds and kilograms, or other units of measure.Use the Unit and Converter classes.There are various systems of measurement used throughout the world. For example, temperature is commonly measured in both Fahrenheit and Celsius. Weight is sometimes measured in pounds, but quite frequently, a metric system that uses kilograms is employed instead. And distances are likely to be measured in miles instead of kilometers, or inches instead of centimeters. For these reasons, you may need to convert from one unit of measure to another.Technically, pounds are a measurement of weight, while kilograms are a measurement of mass. Weight is a force that changes as the acceleration due to gravitational changes, whereas mass is constant regardless of the effects of gravity. The effect is that an object’s weight on the moon and Earth differ since there are different effects, thanks to gravity, but the mass of an object remains the same. However, on the surface of the Earth, mass and weight often are used interchangeably.Each of these conversions has its own algorithm. For example, to convert from Centigrade to Fahrenheit, you should multiply by 9, divide by 5, and then add 32 (to convert from Fahrenheit to Centigrade, subtract 32, multiply by 5, and then divide by 9). Likewise, you can multiply by 2.2 to convert pounds to kilograms, and you can divide by 2.2 to convert kilograms to pounds. (We also saw in Recipe 4.12 how to convert angles from degrees to radians and vice versa.)As with converting between different units of measure with angles, you can use the Unit and Converter classes to convert between other types of units. The Unit class has support for quite a range of categories of measurement (angles, temperature, volume, etc.). You can retrieve an array of supported categories using the staticEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- Chapter 5: Arrays
- InhaltsvorschauArrays are essential to successful ActionScript programming.An array provides a way of grouping related data together, and then organizing and processing that data. The concept of an array should not be foreign to you. In fact, the concept is used all the time in everyday life. You can view a simple grocery list or to-do list as an array. Your address book is an array containing people’s names, addresses, birthdates, and so on. Libraries keep track of books using an indexing system whereby each book becomes, conceptually, an element in a library’s array.In ActionScript, there are two kinds of arrays: integer-indexed and associative. Both array types group related data, but they use different means of accessing the data.
- Integer-indexed array
-
Uses integers (numbers) as unique identifiers for each element in the array. Such arrays are ordered by index (i.e., element number), starting from 0. Each element occupies a numbered slot in the array. Integer-indexed arrays are ideal for sets of data that you want to work with in sequential order.
- Associative array
-
Uses string keys to access each value. You can read more about associative arrays in Recipe 5.15.
Integer-indexed arrays are the focus of the majority of the recipes in this chapter, and unless otherwise specified, the term “array” refers to an integer-indexed array.Of course, before you can use an array, you first need to know how to create one. There are two ways to construct a new array in ActionScript: with the constructor function or as an array literal. All arrays are members of the Array class. You can use the Array( ) constructor function to instantiate new array objects in one of three ways:// Create an empty array. var array:Array = new Array(); // Create an array with
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Introduction
- InhaltsvorschauArrays are essential to successful ActionScript programming.An array provides a way of grouping related data together, and then organizing and processing that data. The concept of an array should not be foreign to you. In fact, the concept is used all the time in everyday life. You can view a simple grocery list or to-do list as an array. Your address book is an array containing people’s names, addresses, birthdates, and so on. Libraries keep track of books using an indexing system whereby each book becomes, conceptually, an element in a library’s array.In ActionScript, there are two kinds of arrays: integer-indexed and associative. Both array types group related data, but they use different means of accessing the data.
- Integer-indexed array
-
Uses integers (numbers) as unique identifiers for each element in the array. Such arrays are ordered by index (i.e., element number), starting from 0. Each element occupies a numbered slot in the array. Integer-indexed arrays are ideal for sets of data that you want to work with in sequential order.
- Associative array
-
Uses string keys to access each value. You can read more about associative arrays in Recipe 5.15.
Integer-indexed arrays are the focus of the majority of the recipes in this chapter, and unless otherwise specified, the term “array” refers to an integer-indexed array.Of course, before you can use an array, you first need to know how to create one. There are two ways to construct a new array in ActionScript: with the constructor function or as an array literal. All arrays are members of the Array class. You can use the Array( ) constructor function to instantiate new array objects in one of three ways:// Create an empty array. var array:Array = new Array(); // Create an array with
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Adding Elements to the Start or End of an Array
- InhaltsvorschauYou want to add elements to an existing array.Use the push( ) method to append elements to the end of an array; use the unshift( ) method to insert elements at the beginning of an array.You append elements to the end of an existing array using the Array.push( ) method, passing it one or more values to be appended:
var array:Array = new Array(); array.push("val 1", "val 2");You can also append a single element by using the array’slengthproperty as the index. Because ActionScript array indexes are zero-indexed (meaning that the first index is 0, not 1), the last element is at an index of Array.length- 1. Therefore, putting an element at index Array.lengthcreates a new element right after the current last element; for example:array[array.length] = "val 3";
If you set an element with an index that doesn’t exist, the array extends itself to include the necessary number of elements automatically. If there are any intervening elements, they are initialized toundefined. For example,letterswill contain the elements["a", "b", "c", undefined, undefined, "f"]after you execute the following statements:var letters:Array = ["a", "b", "c"]; letters[5] = "f";
Appending elements onto an array is common when you want to build an array incrementally or when you want to store the history of a user’s actions for the purpose of implementing a back button or history feature.To add elements to the beginning of an array, use the unshift( ) method. This shifts the existing elements up by one index position, and inserts the new element at index 0:// Create an array with four elements: // "a", "b", "c", and "d". var letters:Array = new Array( ); letters.push("a", "b", "c", "d"); // Add "z" to the beginning of the array. This shifts all // the other elements so the value of "a" moves from // index 0 to index 1, etc. letters.unshift("z"); // Display the results by looping through the elements. // See Recipe 5.2. for (var i:int = 0; i < letters.length; i++) { trace(letters[i]); }Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Looping Through an Array
- InhaltsvorschauYou want to access each element of an array in sequential order.Use a for loop that increments an index variable from 0 until it reaches Array.
length. Use the index to access each element in turn.To access the values stored in the elements of an array, loop through the array’s elements using a for loop. Because the first index of an array is 0, the index variable in the for statement should start at 0. The last index of an array is always 1 less than thelengthproperty of that array. Within the for statement, use the loop index variable within square brackets to access array elements. For example:var letters:Array = ["a", "b", "c"]; for (var i:int = 0; i < letters.length; i++) { // Display the elements in the Output panel. trace("Element " + i + ": " + letters[i]); }The looping index variable (i in the example code) should range from 0 to one less than the value of thelengthproperty. Remember that the last index of an array is always one less than itslength.Alternatively, you can use a for statement that loops backward from Array.length-1 to 0, decrementing by one each time. Looping backward is useful when you want to find the last matching element rather than the first (see Recipe 5.3), for example:var letters:Array = ["a", "b", "c"]; for (var i:int = letters.length - 1; i >= 0; i--){ // Display the elements in reverse order. trace("Element " + i + ": " + letters[i]); }There are many instances when you might want to loop through all the elements of an array. For example, by looping through an array containing references to sprites, you can perform a particular action on each of the sprites:for (var i:int = 0; i < sprites.length; i++){ // Move each sprite one pixel to the right. sprites[i].x++; }You can store the array’sEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Searching for Matching Elements in an Array
- InhaltsvorschauYou want to find the first element in an array that matches a specified value.Use a for statement to loop through an array and a break statement once a match has been found. Optionally, use the ArrayUtilities.findMatchIndex( ), ArrayUtilities.findLastMatchIndex( ), and/or ArrayUtilities.findMatchIndices( ) methods.When you search for the first element in an array that matches a specified value, you should use a for statement, as shown in Recipe 5.2, and add a break statement to exit the loop once the match has been found.Using a break statement within a for statement causes the loop to exit once it is encountered. You should place the break statement within an if statement so it is executed only when a certain condition is met.When searching for the first matching element, the importance of the break statement is twofold. First, you don’t need to loop through the remaining elements of an array once the match has been found; that would waste processing time. In the following example, the break statement exits the loop after the second iteration, saving six more needless iterations. (Imagine the savings if there were a thousand more elements!)Furthermore, the break statement is vital when searching for the first match because it ensures that only the first element is matched and that subsequent matches are ignored. If the break statement is omitted in the following example—all matching elements are displayed, as opposed to the first one only.
// Create an array with eight elements. var letters:Array = ["a", "b", "c", "d", "a", "b", "c", "d"]; // Specify what we want to search for. var match:String = "b"; // Use a for statement to loop through, potentially, // all the elements of the array. for (var i:int = 0; i < letters.length; i++) { // Check whether the current element matches // the search value. if (letters[i] == match) { // Do something with the matching element. // In this example, display a message // for testing purposes. trace("Element with index " + i + " found to match " + match); // Include aEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Removing Elements
- InhaltsvorschauYou want to remove one or more elements from an array and shift any remaining elements to fill the vacant indexes.Use the splice( ) method to remove elements from the middle of the array. Use pop( ) to remove the last element or shift( ) to remove the first element.Remove elements from an array by starting at a specified index using the splice( ) method. When using splice( ) to delete elements, you should pass it two parameters:
start-
The index of the array from which to start deleting elements.
deleteCount-
The number of elements to delete. If this value is
undefined, all the elements from start to the end of the array are deleted:var letters:Array = ["a", "b", "c", "d"]; // Remove one element from letters starting at index 1. letters.splice(1, 1); // Display the results. The array now contains three elements: // "a", "c", and "d". for (var i:int = 0; i < letters.length; i++) { trace(letters [i]); }
The splice( ) method also returns a new array containing the deleted elements; for example:var letters:Array = ["a", "b", "c", "d"]; // Remove two elements from letters starting at index 0. var deleted:Array = letters.splice(0, 2); // Display the deleted elements: "a" and "b". for (var i:int = 0; i < deleted.length; i++) { trace(deleted[i]); }To delete a single element from the beginning or end of the array, you can use the shift( ) and pop( ) methods. The shift( ) method removes the first element of the array and returns its value. The pop( ) method removes the last element of the array and returns its value:var letters:Array = ["a", "b", "c", "d"]; // Remove the first element and display its value. trace(letters.shift( )); // Remove the last element and display its value. trace(letters.pop( )); // Display the remaining elements. // The array has two elements left: "b" and "c". for (var i = 0; i < letters.length; i++) { trace(letters[i]); }Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Inserting Elements in the Middle of an Array
- InhaltsvorschauYou want to insert elements in the middle of an array.Use the splice( ) method.You can use the splice( ) method to insert elements as well as delete them. Values passed to the splice( ) method after the first and second parameters are inserted into the array at the index specified by the start parameter; all existing elements following that index are shifted up to accommodate the inserted values. If 0 is passed to the splice( ) method for the deleteCount parameter, no elements are deleted, but the new values are inserted:
var letters:Array = ["a", "b", "c", "d"]; // Insert three string values ("one", "two", and "three") // starting at index 1. letters.splice(1, 0, "r", "s", "t"); // letters now contains seven elements: // "a", "r", "s", "t", "b", "c", and "d". for (var i:int = 0; i < letters.length; i++) { trace(letters[i]); }You can also delete elements and insert new elements at the same time:var letters:Array = ["a", "b", "c", "d"]; // Remove two elements and insert three more // into letters starting at index 1. letters.splice(1, 2, "r", "s", "t"); // myArray now contains five elements: // "a", "r", "s", "t", and "d". for (var i:int = 0; i < letters.length; i++) { trace(letters[i]); }Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Converting a String to an Array
- InhaltsvorschauYou have a list of values as a string and you want to parse it into an array of separate elements.Use the String.split( ) method.The split( ) method of the String class splits a string containing a list of values into an array. The list must be delimited by a uniform substring. For example, the list Susan,Robert,Paula is comma-delimited.The split( ) method takes up to two parameters:
delimiter-
The substring that is used to delimit the elements of the list. If
undefined, the entire list is placed into the first element of the new array. limit-
The maximum number of elements to place into the new array. If
undefined, all the elements of the list are placed into the new array.
You can use a space as the delimiter to split a string into an array of words:var list:String = "Peter Piper picked a peck of pickled peppers"; // Split the string using the space as the delimiter. This puts // each word into an element of the new array, words. var words:Array = list.split(" ");The split( ) method can be extremely useful when values are loaded into Flash using a URLLoader object or another similar technique for loading data. For example, you might retrieve a list of names as a string from the server such as the following:names=Michael,Peter,Linda,Gerome,Catherine
You can make it easier to use the names by parsing them into an array using the split( ) method:// Assume _loader is the URLLoader used to load the data. var namesData:String = _loader.data; var names:Array = namesData.split(",");Recipe 5.7Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Converting an Array to a String
- InhaltsvorschauYou want to convert an array to a string.Use the join( ) method.ActionScript provides you with a built-in way to quickly convert arrays to strings (assuming, of course, that the array elements themselves are either strings or another datatype that ActionScript can automatically cast to a string) using the join( ) method. You should pass the join( ) method a string that tells Flash which delimiter to use to join the elements:
var letters:Array = ["a", "b", "c"]; trace(letters.join("|")); // Displays: a|b|cIf you don’t provide a delimiter, Flash uses a comma by default:var letters:Array = ["a", "b", "c"]; trace(letters.join()); // Displays: a,b,c
The toString( ) method does the same thing as the join( ) method either with no parameters or with the comma as the parameter. In fact, if you try to use an array in a situation in which a string is required, Flash automatically calls the toString( ) method, as follows:var letters:Array = ["a", "b", "c"]; trace(letters); // Displays: a,b,c
Recipe 5.6Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Creating a Separate Copy of an Array
- InhaltsvorschauYou want to make an exact copy (a duplicate) of an array—one that contains all of the elements found in the original, but is not just another reference to the original.Use the concat( ) method or the slice( ) method. Optionally, you can use the ArrayUtilities.duplicate( ) method. The duplicate( ) method can create recursive duplicates.Because arrays are a composite datatype, they are copied and compared differently from primitive data. A variable that holds an array doesn’t truly contain all of the array’s data. Instead, the variable simply points to the place in the computer’s memory where the array’s data resides. This makes sense from an optimization standpoint. Primitive data tends to be small, such as a single number or a short string. But composite data, such as an array, can be very large. It would be inefficient to copy an entire array every time you wanted to perform an operation on it or pass it to a function. Therefore, when you try to copy an array, ActionScript doesn’t make a separate copy of the array’s data. A simple example illustrates this.First, let’s look at how primitive data is copied from the variable
quantityto another variable,newQuantity:// Assign the number 5 to a variable. var quantity:int = 5; // Copy quantity's value to another variable, newQuantity. var newQuantity:int = quantity; // Change quantity's value. quantity = 29; trace(quantity); // Displays: 29 trace(newQuantity); // Displays: 5
When the copy is made, the contents ofquantityare copied tonewQuantity. After the copy is made, subsequent changes toquantityhave no effect onnewQuantity(and vice versa) because primitive data is copied by value.Now let’s look at a similar operation with arrays; however, note the difference from the preceding example. The variableEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Storing Complex or Multidimensional Data
- InhaltsvorschauYou have two or more sets of related data and you want to be able to keep track of the relationships between their elements.Use parallel arrays, an array of arrays (a multidimensional array), or an array of objects.You can create two or more parallel arrays in which the elements with the same index in each array are related. For example, the beginGradientFill() method, discussed in Chapter 7, uses three parallel arrays for the colors, alphas, and ratios of the values used in the gradient. In each array, the elements with the same index correspond to one another.To create parallel arrays, populate multiple arrays such that the elements with the same index correspond to one another. When you use parallel arrays, you can easily retrieve related data, since the indexes are the same across the arrays; for example:
var colors:Array = ["maroon", "beige", "blue", "gray"]; var years:Array = [1997, 2000, 1985, 1983]; var makes:Array = ["Honda", "Chrysler", "Mercedes", "Fiat"]; // Loop through the arrays. Since each array is the same // length, you can use the length property of any of them // in the for statement. Here, we use makes.length. for (var i:int = 0; i < makes.length; i++) { // Displays: // A maroon 1997 Honda // A beige 2000 Chrysler // A blue 1985 Mercedes // A gray 1983 Fiat // Display the elements with corresponding indexes // from the arrays. trace("A " + colors[i] + " " + years[i] + " " + makes[i]); }Be careful when manipulating parallel arrays. If you add or remove elements from the arrays, you have to be certain to add or remove related data at the same position in every array. Otherwise the arrays will be out of sync and useless.Another option for working with multiple sets of data is to create a multidimensional array, which is an array of arrays (i.e., an array in which each element is another array):Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Sorting or Reversing an Array
- InhaltsvorschauYou want to sort the elements of an array.Use the sort( ) method. For arrays of objects, you can also use the sortOn( ) method.You can perform a simple sort on an array using the sort( ) method. The sort( ) method, without any parameters, sorts the elements of an array in ascending order. Elements are sorted according to the Unicode code points of the characters in the string (roughly alphabetical for Western European languages).
var words:Array = ["tricycle", "relative", "aardvark", "jargon"]; words.sort( ); trace(words); // Displays: aardvark,jargon,relative,tricycle
The sort( ) method, by default, is very useful if you want to sort the elements of an array in ascending, alphabetical order. However, there are some caveats. Namely, the sort is case-sensitive, and it sorts numbers “alphabetically” instead of numerically. Fortunately, ActionScript allows you to pass one of several constants to the sort( ) method in order to sort with different guidelines.You sort an array in descending order using the Array.DESCENDING constant:var words:Array = ["tricycle", "relative", "aardvark", "jargon"]; words.sort(Array.DESCENDING); trace(words); // Displays: tricycle,relative,jargon,aardvark
As mentioned, the sort( ) method runs a case-sensitive sort by default. It places elements starting with uppercase characters before elements starting with lowercase characters. The following illustrates the point:var words:Array = ["Tricycle", "relative", "aardvark", "jargon"]; words.sort( ); trace(words); // Displays: Tricycle,aardvark,jargon,relative
You can use the Array.CASEINSENSITIVE constant to run a case-insensitive sort:var words:Array = ["Tricycle", "relative", "aardvark", "jargon"]; words.sort(Array.CASEINSENSITIVE); trace(words); // Displays: aardvark,jargon,relative,Tricycle
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Implementing a Custom Sort
- InhaltsvorschauYou want to sort an array using more complex logic than an alphabetical or numeric sort.Use the sort( ) method and pass it a reference to a compare function.If you want complete control over sorting criteria, use the sort( ) method with a custom compare function (also called a sorter function). The sort( ) method repeatedly calls the compare function to reorder two elements of an array at a time. It sends the compare function two parameters (let’s call them a and b). The compare function then determines which one should be ordered first by returning a positive number, a negative number, or 0, depending on how the elements are to be sorted. If the function returns a negative number, a is ordered before b. If the function returns 0, then the current order is preserved. If the function returns a positive number, a is ordered after b. The sort( ) method calls the compare function with every relevant combination of elements until the entire array has been properly ordered. Using a custom compare function is easier than it sounds. You don’t need to concern yourself with the details of sorting the entire array; you simply specify the criteria for comparing any two elements.One example of when you would want to use a custom sorter is when you need to sort a list of strings, but you need to process the strings somehow before sorting them. Say you are building a music program that needs to display a list of bands. If you just sorted the bands alphabetically, all the bands whose names began with “The” would appear together in the T section, which is probably not what you want. You can define a compare function that strips off “The” from the beginning of the name before comparing the bands. Here is the code to set up the array, perform a simple sort, and display the results:Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- Randomizing the Elements of an Array
- InhaltsvorschauYou want to randomize the elements of an array.Use the sort( ) method with a compare function that randomly returns a positive or negative number.There are lots of scenarios in which you might plausibly want to randomize the elements of an array. For example, you may have a game in which you want to randomize the letters of a word. Since you already know how to split the letters into elements of an array using the split( ) method, you may need to randomize those elements. Or perhaps you are making a card game where each element in the array is a card, and you want to shuffle the deck.There is more than one way to accomplish the task. However, one of the simplest ways is to create a compare function that randomly returns a positive or negative number, and use it in the sort( ) method. See Recipe 5.11 for more information on compare functions.The following is probably the simplest possible compare function for the job:
function randomSort(elementA:Object, elementB:Object):Number { return Math.random( ) - .5 }Math.random( )returns a number between 0.0 and 1.0. If you subtract 0.5 from that number, you’ll get a random number between -0.5 and 0.5. Remember that in a compare function, returning a negative number means to order the first element first, and a positive number tells the sort( ) method to put the second element first. Since the odds you’ll return are 50/50, the resulting order of the array is completely random.The following is an example of randomizing an array:var numbers:Array = new Array( ); for(var i:int=0;i<20;i++) { numbers[i] = i; } numbers.sort(randomSort); for(var i:int=0;i<numbers.length;i++) { trace(numbers[i]); }This creates an array of 20 sequential numbers, and then randomizes and displays them. You can verify that the order is now quite random.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Getting the Minimum or Maximum Element
- InhaltsvorschauYou want to retrieve the minimum or maximum element from an array of numbers.Sort the array numerically, and then retrieve the first or last element from the sorted array.You can quickly retrieve the minimum or maximum value from an array by sorting it. The following example illustrates how to do just that:
var scores:Array = [10, 4, 15, 8]; scores.sort(Array.NUMERIC); trace("Minimum: " + scores[0]); trace("Maximum: " + scores[scores.length - 1]);Of course, if the existing order of the array is important, you’ll want to make a copy of the array before sorting it. See Recipe 5.8.You can optionally use the ArrayUtilities.min( ) and ArrayUtilities.max( ) methods.Recipe 5.8Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Comparing Arrays
- InhaltsvorschauYou want to compare two arrays to see if they are equivalent.Loop through each element of both arrays and compare them.Since arrays are reference datatypes, using an equality operator with two array variables only checks to see if they point to the same spot in memory. For example:
var letters:Array = ["a", "b", "c", "d"]; var lettersPointer:Array = letters; trace(letters == lettersPointer); // Displays: true
However, if two arrays are equivalent yet don’t point to the same spot in memory, an equality operation returnsfalse:var letters1:Array = ["a", "b", "c", "d"]; var letters2:Array = ["a", "b", "c", "d"]; trace(letters1 == letters2]; // Displays: false
Instead, you can loop through each of the elements of the arrays and compare them:var equivalent:Boolean = true; for(var i:int = 0; i < letters1.length; i++) { if(letters1[i] != letters2[i]) { equivalent = false; break; } } trace(equivalent); // Displays: trueOptionally, you can use the ArrayUtilities.equals( ) method. This method requires two parameters: the references to the two arrays to compare. The method returns a Boolean value that indicates whether the arrays are equivalent or not:var letters1:Array = ["a", "b", "c", "d"]; var letters2:Array = ["a", "b", "c", "d"]; trace(ArrayUtilities.equals(letters1, letters2)); // Displays: true
By default, the order of the elements has to match in the two arrays. If you don’t care whether the order of the elements matches, you can specify a third parameter for the equals( ) method; a Boolean value indicating whether or not the order should be disregarded:var letters1:Array = ["a", "b", "c", "d"]; var letters2:Array = ["b", "a", "d", "c"]; trace(ArrayUtilities.equals(letters1, letters2)); // Displays: false trace(ArrayUtilities.equals(letters1, letters2, true)); // Displays: true
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Creating an Associative Array
- InhaltsvorschauYou want to create an array that uses named elements instead of numbered indexes.Create an associative array.When working with sets of data in which each element has a specific meaning or importance, a typical, number-indexed array doesn’t always suffice.For example, if you are working with a set of data such as the names of members of a committee, a number-indexed array is sufficient:
var aMembers:Array = new Array("Franklin", "Gina", "Sindhu");However, if each member of the committee plays a special role, a standard array offers no way to indicate that. To address the issue, you can use an associative array. In some languages, this is called a hash table. In ActionScript, it is actually just an instance of the Object class. An associative array uses named elements rather than numeric indexes. The names used to refer to elements are often called keys or properties. The keys can give a meaningful context to the associated element value.You can create an associative array in ActionScript by using object literal notation or adding elements to an object. Despite their name, you don’t use the Array class to create associative arrays. The Array class provides methods and properties that work with number-indexed arrays only—and not with associative arrays. Associative arrays should be instances of the Object class. Technically, since the Object class is the base class for all ActionScript classes, all ActionScript objects can be used as associative arrays. However, unless you have some specific reason for using another class as an associative array, it is best to simply use the generic Object class.One way you can create an associative array is by using object literal notation. With this technique, use curly braces ({ }) to enclose a comma-delimited list of keys and values, which are separated by a colon (Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Reading Elements of an Associative Array
- InhaltsvorschauYou want to loop through the elements of an associative array.Use a for . . . in statement.You iterate through the elements of integer-indexed arrays by using a for statement. However, named elements in associative arrays cannot be accessed by a numeric index, and the order of associative array elements is not guaranteed, regardless of the order in which the elements are added to the array. For that reason, there are also no methods to sort or reverse an associative array, or otherwise change its order.Fortunately, you can loop through the enumerable elements of an associative array by using a for . . . in statement. This statement iterates through all the readable properties of the specified object. The syntax for a for . . . in statement is as follows:
for (key in object) { // Actions }
The for . . . in statement doesn’t require an explicit update statement because the number of loop iterations is determined by the number of properties in the object being examined. Note that key is a variable name that will be used to store the property name during each iteration, not the name of a specific property or key. On the other hand, object is the specific object whose properties you want to read. For example:var members:Object = new Object( ); members.scribe = "Franklin"; members.chairperson = "Gina"; members.treasurer = "Sindhu"; // Use a for . . . in statement to loop through all elements. for (var sRole:String in members) { // Displays: // treasurer: Sindhu // chairperson: Gina // scribe: Franklin trace(sRole + ": " + members[sRole]); }When you use a for . . . in statement, you must use array-access notation (square brackets) with the associative array. If you try to use property notation (with the dot operator) it won’t work properly. This is because the value that is assigned to the key iterator variable is theEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Chapter 6: Display List
- InhaltsvorschauThe rendering model for ActionScript 3.0 and Flash Player 9 is radically different than in previous versions. Traditionally, the MovieClip was the focal point of the renderer. Every .swf movie contained a root MovieClip (commonly referred to as the Stage). The root MovieClip could contain child MovieClips, which could, in turn, contain more child MovieClips. The concept of depths was used to control the stacking order in which MovieClips were drawn (objects on higher depths appear “on top”). Methods such as createEmptyMovieClip( ), attachMovie( ), or duplicateMovie- Clip( ) were used to create MovieClips. Anytime a MovieClip was created, it was automatically added into the visual hierarchy and consequently drawn by the renderer. MovieClips weren’t able to move to different places within the hierarchy; instead, they first had to be destroyed and then recreated before they could be positioned elsewhere in the display.The new renderer is still hierarchical, but not as rigid, and aims to simplify and optimize the rendering process. The new rendering model centers on the display list concept and focuses on the classes available in the flash.display package. The display list is a hierarchy that contains all visible objects in the .swf movie. Any object not on the display list is not drawn by the renderer. Each .swf movie contains exactly one display list, which is comprised of three types of elements:
- The stage
-
The stage is the root of the display list hierarchy. Every movie has a single stage object that contains the entire object hierarchy of everything displaying on the screen. The stage is a container that typically contains only a single child, the main application class of the .swf movie. You can access the stage by referring to the
stageproperty on any display object in the display list.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Introduction
- InhaltsvorschauThe rendering model for ActionScript 3.0 and Flash Player 9 is radically different than in previous versions. Traditionally, the MovieClip was the focal point of the renderer. Every .swf movie contained a root MovieClip (commonly referred to as the Stage). The root MovieClip could contain child MovieClips, which could, in turn, contain more child MovieClips. The concept of depths was used to control the stacking order in which MovieClips were drawn (objects on higher depths appear “on top”). Methods such as createEmptyMovieClip( ), attachMovie( ), or duplicateMovie- Clip( ) were used to create MovieClips. Anytime a MovieClip was created, it was automatically added into the visual hierarchy and consequently drawn by the renderer. MovieClips weren’t able to move to different places within the hierarchy; instead, they first had to be destroyed and then recreated before they could be positioned elsewhere in the display.The new renderer is still hierarchical, but not as rigid, and aims to simplify and optimize the rendering process. The new rendering model centers on the display list concept and focuses on the classes available in the flash.display package. The display list is a hierarchy that contains all visible objects in the .swf movie. Any object not on the display list is not drawn by the renderer. Each .swf movie contains exactly one display list, which is comprised of three types of elements:
- The stage
-
The stage is the root of the display list hierarchy. Every movie has a single stage object that contains the entire object hierarchy of everything displaying on the screen. The stage is a container that typically contains only a single child, the main application class of the .swf movie. You can access the stage by referring to the
stageproperty on any display object in the display list.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Adding an Item to the Display List
- InhaltsvorschauYou want to add a new display object to the display list so it appears on-screen.Use the addChild( ) and addChildAt( ) methods from the DisplayObectContainer class.The Flash Player is composed of two main pieces that function together to form a cohesive unit, the ActionScript Virtual Machine (AVM) and the Rendering Engine. The AVM is responsible for executing ActionScript code, and the Rendering Engine is what draws objects on-screen. Because the Flash Player is composed of these two main pieces, drawing an object on the screen is a two-step process:
-
The display object needs to be created in the ActionScript engine.
-
The display object is then created in the rendering engine and drawn on-screen.
The first step is done by using thenewoperator to create an instance of the display object. Any object that is going to be added to the display list must be either a direct or indirect subclass of DisplayObject, such as Sprite, MovieClip, TextField, or a custom class you create (according to Recipe 6.4). To create a TextField instance you would use the following code:var hello:TextField = new TextField( );
The preceding line of code creates a TextField display object in the AVM, but the object is not drawn on the screen yet because the object doesn’t exist in the Rendering Engine. To create the object in the Rendering Engine, the object needs to be added to the display list hierarchy. This can be done by calling the addChild( ) or addChildAt( ) method from a DisplayObjectContainer instance that is itself already on the display list hierarchy.The addChild( ) method takes a single parameter—the display object that the container should add as a child. The following code is a complete example that demonstrates how to create an object in the AVM and then create the object in the Rendering Engine by adding it to the display list:Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Removing an Item from the Display List
- InhaltsvorschauYou want to remove an item from the display list and consequently remove it from the screen.Use the removeChild( ) and removeChildAt( ) methods from the DisplayObectContainer class.Recipe 6.1 demonstrates how to add display objects to the display list using the addChild( ) and addChildAt( ) methods. To achieve the opposite effect and remove a child via one of these methods, use either the removeChild( ) or removeChildAt( ) method.The removeChild( ) method takes a single parameter, which is a reference to the display object that should be removed from the container. If an object is supposed to be removed and it isn’t a child of the container, an ArgumentError is thrown:
package { import flash.display.Sprite; import flash.text.TextField; import flash.events.MouseEvent; public class RemoveChildExample extends Sprite { // Create a local variable to store a reference // to the TextField so that we can remove it later private var _label:TextField; public function RemoveChildExample( ) { _label = new TextField( ); _label.text = "Some Text"; // Add the hello TextField to the display list addChild( _label ); // When the mouse is clicked anywhere on the stage, // remove the label stage.addEventListener( MouseEvent.CLICK, removeLabel ); } // Removes the label from this container's display list public function removeLabel( event:MouseEvent ):void { removeChild( _label ); } } }The preceding code example creates a local variablelabelthat stores a reference to the TextField within the class itself. This is a necessary step because the removeChild( ) method must be passed a reference to the display object to remove, solabelis used to store the reference for later. Iflabelwere not available, extra work would be required to get a reference to theEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Moving Objects Forward and Backward
- InhaltsvorschauYou want to change the order in which objects are drawn on-screen, moving them either in front of or behind other display objects.Use the setChildIndex( ) method of the DisplayObectContainer class to change the position of a particular item. Use the getChildIndex( ) and getChildAt( ) methods to query siblings of the item so the item can be positioned properly relative to them.Recipes 6.1 and 6.2 introduced how the display list model deals with the visual stacking order (depth). Essentially, every DisplayObjectContainer instance has a list of children, and the order of the children in this list determines the order in which child display objects are drawn inside of the container. The children are each given a position index, ranging from 0 to
numChildren– 1, much like an array. The child at position 0 is drawn on the bottom, underneath the child at position 1, etc. There are no empty position values in the list; if there are three children, the children will always have index values of 0, 1, and 2 (and not, say, 0, 1, and 6).The setChildIndex( ) method is provided by DisplayObjectContainer to reorder the children inside the container. It takes two parameters: a reference to the child to be moved and the child’s new position in the container. The index position specified must be a valid value. Negative values or values too large will generate a RangeError and the function won’t execute properly.The following example creates three colored circles, with the blue one being drawn on top. The setChildIndex( ) method is used to move the blue circle underneath the two other circles, changing its position from 2 to 0 in the container. The positions of the other children are adjusted accordingly; red is moved to 1 and green is moved to 2:Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Creating Custom Visual Classes
- InhaltsvorschauYou want to create a new type of DisplayObject.Create a new class that extends DisplayObject or one of its subclasses so it can be added into a display object container via addChild( ) or addChildAt( ).Among the benefits of moving toward the display list model is the ease of creating new visual classes. In the past, it was possible to extend MovieClip to create custom visuals, but there always had to be a MovieClip symbol in the library linked to the ActionScript class to create an on-screen instance via attachMovie( ). Creating a custom visual could never be done entirely in ActionScript. With the display list model, the process has been simplified, allowing you to do everything in pure ActionScript code in a much more intuitive manner.In the display list model, as discussed in the introduction of this chapter, there are many more display classes available besides just MovieClip. Before you create your custom visual, you need to decide which type it is going to be. If you’re just creating a custom shape, you’ll want to extend the Shape class. If you’re creating a custom button, you’ll probably want to extend SimpleButton. If you want to create a container to hold other display objects, Sprite is a good choice if you don’t require the use of a timeline. If you need a timeline, you’ll need to subclass MovieClip.All of the available display object classes are tailored for specific purposes. It’s best to decide what purpose your own visual class is going to serve, and then choose the appropriate parent class based on that. By choosing the parent class carefully you optimize size and resource overhead. For example, a simple Circle class doesn’t need to subclass MovieClip because it doesn’t need the timeline. The Shape class is the better choice in this case because it’s the most lightweight option that appropriately fits the concept of a circle.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- Creating Simple Buttons
- InhaltsvorschauYou want to create an interactive button that enables a user to click and perform an action, such as submitting a form or calculating a total.Create an instance of the SimpleButton class and create display objects for
upState,downState,overState, andhitTestState. Alternatively, create a subclass of SimpleButton that describes your desired button behavior.Use theclickevent to invoke a method whenever the user presses the button.The display list model provides an easy way to create buttons through the SimpleButton class. The SimpleButton class allows a user to interact with the display object using their mouse, and makes it easy for you to define that interaction through various button states. The possible button states, listed here, are available as properties of the SimpleButton class:upState-
A display object for the default “up” state of the button. The “up” state is shown whenever the mouse is not over the button.
overState-
A display object that determines what the button looks like when the mouse moves over the button. When the mouse leaves the button area, the button moves back to the “up” state.
downState-
A display object that’s shown when the button is pressed (or clicked) “down”. When the button is in the “over” state, the “down” state displays when the user presses the left mouse button.
hitTestState-
A display object that defines a button’s bounds. When the mouse moves inside of the button’s hit area, the button enters the “over” state. The
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Loading External Images at Runtime
- InhaltsvorschauYou want to load an external image into a movie while it plays.Use the new Loader class to load an image ( .jpg, progressive .jpg, .png, or .gif) and display it on-screen.Recipe 9.17 demonstrates how to embed external assets into a movie at compile time via the
[Embed]metadata tag. To load external images or movies at runtime during the playback of a .swf, the Loader class needs to be used.The flash.display.Loader class is very similar to the flash.net.URLLoader class discussed in Recipe 19.3. One of the key differences is that Loader instances are able to load external images and movies and display them on-screen, whereas URLLoader instances are useful for transferring data.There are three fundamental steps for loading external content:-
Create an instance of the Loader class.
-
Add the Loader instance to the display list.
-
Call the load( ) method to pull in an external asset.
The load( ) method of the Loader class is responsible for downloading the image or .swf file. It takes a single URLRequest object as a parameter that specifies the URL of the asset to download and display.The following is a small example of using a Loader instance to download an image named image.jpg at runtime. The code in the LoaderExample constructor has been commented to coincide with the three basic loading steps previously outlined:package { import flash.display.*; import flash.net.URLRequest; public class LoaderExample extends Sprite { public function LoaderExample( ) { // 1. Create an instance of the Loader class var loader:Loader = new Loader( ); // 2. Add the Loader instance to the display list addChild( loader ); // 3. Call the load( ) method to pull in an external asset loader.load( new URLRequest( "image.jpg" ) ); } } }Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Loading and Interacting with External Movies
- InhaltsvorschauYou want to load, and be able to interact with, an external .swf movie into your own movie.Use the new Loader class to load the .swf file, and then access the .swf file via the
contentproperty of the Loader instance.Recipe 6.6 demonstrates how to load external images via the Loader class. Loading external .swf movies uses the same technique—by calling the load( ) method on a Loader instance and passing a URL to a .swf instead of an image, the .swf is loaded into the movie. If the Loader is in the main display hierarchy, the .swf also appears on-screen.This recipe involves creating two separate .swf files, ExternalMovie.swf and LoaderExample.swf. The first movie, ExternalMovie.swf, will be loaded at runtime into the second movie, LoaderExample.swf. The code for ExternalMovie.swf is as follows:package { import flash.display.Sprite; import flash.display.Shape; public class ExternalMovie extends Sprite { private var _color:uint = 0x000000; private var _circle:Shape; public function ExternalMovie( ) { updateDisplay( ); } private function updateDisplay( ):void { // If the circle hasn't been created yet, create it // and make it visible by adding it to the display list if ( _circle == null ) { _circle = new Shape( ); addChild( _circle ); } // Clear any previously drawn content and draw // a new circle with the fill color _circle.graphics.clear( ); _circle.graphics.beginFill( _color ); _circle.graphics.drawCircle( 100, 100, 40 ); } // Changes the color of the circle public function setColor( color:uint ):void { _color = color; updateDisplay( ); } // Gets the current circle color value public function getColor( ):uint { return _color; } } }The code for ExternalMovie.swfEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Creating Mouse Interactions
- InhaltsvorschauYou want users to interact with your movie using their mouse.Use the various mouse events to listen for mouse interactions on display objects of type InteractiveObject. Use the read-only
mouseXandmouseYproperties from DisplayObject to examine the mouse location relative to a display object, or thelocalXandlocalYproperties from the MouseEvent passed to a mouse event handler.Basic mouse interaction can be created with the SimpleButton class, as described in Recipe 6.5. The SimpleButton class provides an easy way to create a clickable button with different button visual states: up, over, and down.However, there are times when buttons just don’t provide enough interactivity. By listening to the various mouse events, you can create interesting interactive experiences. For instance, consider that you want to track the mouse cursor to create an interactive drawing program, drawing lines on-screen based on the user’s mouse movement. Or, consider that you have a maze that a user must navigate their mouse through without colliding with the walls to find the exit. Or, perhaps the user’s mouse movement needs to control the direction of a golf club, and the mouse button is used to swing.These situations require use of the special InteractiveObject display object, which provides the ability to respond to the user’s mouse. If you go back to the introduction for this chapter, you’ll recall that the InteractiveObject class is a base class fairly high in the display object class hierarchy. Because of this, the Sprite, Loader, TextField, and MovieClip classes are all examples of the InteractiveObject class since they fall underneath InteractiveObject in the hierarchy, and you may already be familiar with their use.Instances of the InteractiveObjectEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Dragging and Dropping Objects with the Mouse
- InhaltsvorschauYou want to provide a drag-and-drop-style interface.Use startDrag( ), stopDrag( ) and
dropTargetfrom the Sprite class to implement drag-and-drop behavior. Alternatively, extend the ascb.display.DraggableSprite class for visually smoother dragging behavior using the drag( ) and drop( ) methods.Creating drag-and-drop behavior is not as difficult as you might think. The Sprite class includes methods specifically for the purpose of drag and drop, namely startDrag( ) and stopDrag( ).The startDrag( ) method can be called on any Sprite instance to have it follow the mouse around the screen, creating the dragging effect. To stop dragging, call the stopDrag( ) method on the Sprite instance. After the drag operation is complete, you can examine thedropTargetproperty of the Sprite to determine the object that the Sprite was dropped on. The value ofdropTargetis useful for determining if a drop operation is valid (such as dropping a folder icon on a trashcan to delete it).When calling startDrag( ), you don’t have to specify any parameters; however, the method accepts up to two parameters. The parameters are:lockCenter-
When
truethe center of the Sprite is locked to the mouse position regardless of where the user pressed the mouse. Whenfalsethe Sprite follows the mouse from the location where the user first clicked. The default value isfalse. bounds-
The Rectangle region where you want to constrain dragging. The Sprite is not capable of being dragged outside of this region. The default value is
null, meaning there is no area constraint.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Chapter 7: Drawing and Masking
- InhaltsvorschauWith ActionScript, you can programmatically draw many display objects such as Shape, Sprite, Button, and MovieClip. Each of these classes has a graphics property that is an instance of the flash.display.Graphics class. The Graphics class defines an API for drawing content programmatically. Most recipes in this chapter discuss how to use the Graphics class API.Since the Shape, Sprite, Button, and MovieClip classes already define graphics properties that are references to Graphics instances, it is not necessary to construct new Graphics objects. The graphics property for a display object draws within that display object. For example, the following code sets the line style for the Graphics object targeting a sprite called
sampleSprite:sampleSprite.graphics.lineStyle( );
The Graphics class defines an API for drawing basic lines and simple shapes. However, some common shapes are difficult to draw with the Graphics API. For that reason, the AS3CBLibrary (available at http://www.rightactionscript.com/ascb) includes an ascb.drawing.Pen class. The Pen class is a proxy (a wrapper) for the Graphics class. You can construct a new Pen instance by passing it a reference to the Graphics object you want to target:var pen:Pen = new Pen(sampleSprite.graphics);
The Pen class proxies requests to all the methods of the Graphics class. That means you can call any of the Graphics methods from the Pen class. In addition, the Pen class defines an API that allows you to more simply draw arcs, ellipses, polygons, stars, and more. The Pen class methods are discussed in the relevant recipes in this chapter.You want to set the line style properties.Use the lineStyle( ) method.Before you can draw programmatically, you must set the line style properties for aEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Introduction
- InhaltsvorschauWith ActionScript, you can programmatically draw many display objects such as Shape, Sprite, Button, and MovieClip. Each of these classes has a graphics property that is an instance of the flash.display.Graphics class. The Graphics class defines an API for drawing content programmatically. Most recipes in this chapter discuss how to use the Graphics class API.Since the Shape, Sprite, Button, and MovieClip classes already define graphics properties that are references to Graphics instances, it is not necessary to construct new Graphics objects. The graphics property for a display object draws within that display object. For example, the following code sets the line style for the Graphics object targeting a sprite called
sampleSprite:sampleSprite.graphics.lineStyle( );
The Graphics class defines an API for drawing basic lines and simple shapes. However, some common shapes are difficult to draw with the Graphics API. For that reason, the AS3CBLibrary (available at http://www.rightactionscript.com/ascb) includes an ascb.drawing.Pen class. The Pen class is a proxy (a wrapper) for the Graphics class. You can construct a new Pen instance by passing it a reference to the Graphics object you want to target:var pen:Pen = new Pen(sampleSprite.graphics);
The Pen class proxies requests to all the methods of the Graphics class. That means you can call any of the Graphics methods from the Pen class. In addition, the Pen class defines an API that allows you to more simply draw arcs, ellipses, polygons, stars, and more. The Pen class methods are discussed in the relevant recipes in this chapter.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Setting a Line Style
- InhaltsvorschauYou want to set the line style properties.Use the lineStyle( ) method.Before you can draw programmatically, you must set the line style properties for a Graphics object. If you don’t set the line style properties, the default line style is undefined and lines and fills won’t render. You can set the line style properties by using the lineStyle( ) method of a Graphics object.The lineStyle( ) method accepts up to eight parameters, all of which are optional. The parameters are as follows:
- thickness
-
The thickness (in pixels) for a line. The default value is 1. The valid values range from 0 to 255. 0 is a hairline. Values outside of the valid range are adjusted to the nearest valid value.
- color
-
The color for the line. The default value is
0x000000. - alpha
-
The alpha value for the line. The valid range is from 0 to 1. The default value is 1.
- pixelHinting
-
A Boolean value indicating whether or not the lines ought to snap to whole pixels. The default is
false. - scaleMode
-
One of the constants from the flash.display.LineScaleMode class. The constants are
NORMAL(default),NONE,VERTICAL, andHORIZONTAL. When the value is set toNORMAL, the line thickness scales when the object within which the line is drawn is scaled. For example, if a sprite containing a 1-pixel line is scaled 200 percent, the line thickness scales to 2 pixels. If you set the scale mode toNONE, then the line thickness never scales. If you set the scale mode to
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Setting Gradient Line Styles
- InhaltsvorschauYou want to draw lines using gradient styles.Use the Graphics.lineGradientStyle( ) method.The lineGradientStyle( ) method allows you to draw lines with gradient styles. You must still call lineStyle( ) first. However, once you’ve set the basic line style properties, you can call lineGradientStyle( ) to apply a gradient style to lines. The parameters for the lineGradientStyle( ) method are exactly the same as the parameters for the beginGradientFill( ) method.Recipe 7.13 for more about parameters.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- Drawing a Line
- InhaltsvorschauYou want to draw a line using ActionScript.Use the Graphics.lineTo( ) method to draw a line from the current pen location to a destination point.The most basic type of drawing that you can do with ActionScript is a straight line. Flash uses the current pen location as the starting point, so you need to provide only the coordinates of the destination point. Use the Grahics.lineTo( ) method to create a line from the current pen location to the specified destination point:
// Draws a line from the current pen position to (100,100) // within the coordinate system of sampleSprite. sampleSprite.graphics.lineTo(100, 100);When ActionScript methods are used to draw, all the lines and fills are drawn within the display object associated with the Graphics object from which the methods are invoked. For example, in the preceding code, the line is drawn withinsampleSprite.As mentioned previously, when you use the Drawing API methods such as lineTo( ), Flash draws the line beginning at the current pen location. If you have not otherwise moved the pen (by calling a lineTo( ), curveTo( ), or moveTo( ) method, for example) the pen is positioned at the origin of the display object’s coordinate system, point (0,0). You can move the pen without drawing a line by using the moveTo( ) method. The moveTo( ) method simply relocates the pen to the coordinate you specify; it does not draw any lines:// Move the pen in sampleSprite to (200,20) sampleSprite.graphics.moveTo(200, 20);The moveTo( ) method is important in situations in which you want to either begin drawing from a point other than the display object’s center or draw lines or shapes without necessarily connecting all the lines:// Set a 1-pixel, black, completely opaque line style sampleSprite.graphics.lineStyle( ); // Draw a dashed line using a series of lines and spaces sampleSprite.graphics.lineTo(10, 0); sampleSprite.graphics.moveTo(15, 0); sampleSprite.graphics.lineTo(25, 0); sampleSprite.graphics.moveTo(30, 0); sampleSprite.graphics.lineTo(40, 0); sampleSprite.graphics.moveTo(45, 0); sampleSprite.graphics.lineTo(55, 0);
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Drawing a Curve
- InhaltsvorschauYou want to draw a curve using ActionScript.Use the Graphics.curveTo( ) method.Once you have set a line style, you can draw a curve using the curveTo( ) method. The curveTo( ) method draws an approximation of a Bezier curve (although optimized for performance), which requires three points: a starting point, a control point, and a destination point:
-
The starting point is always determined by the pen’s current location.
-
The destination point is simply the point on the canvas to which you want to draw.
-
The control point is the point that determines the shape of the curve, and it is calculated by determining where the tangents to the curve at the starting and destination points intersect. The control point is not actually on the curve in all cases, except for straight line segments. Figure 7-1 shows the control point for a curve.
Figure 7-1: The control point of a curveThe curveTo( ) method requires four parameters. The first two parameters specify the X and Y coordinates of the control point; the next two parameters specify the X and Y coordinates of the destination point. The following example draws a curve with a control point at 0,100 and a destination point at 100,100:sampleSprite.graphics.lineStyle( ); sampleSprite.graphics.curveTo(0, 100, 100, 100);
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Drawing an Arc
- InhaltsvorschauYou want to draw an arc.Use the Pen.drawArc( ) method.An arc is a part of the outline from a circle. Drawing an arc with the curveTo( ) method is rather difficult for various reasons. However, by using the Pen.drawArc( ) method, you can quickly draw an arc of any radius and length. The drawArc( ) method accepts the following parameters:
- x
-
The x coordinate of the arc center (the center of the circle).
- y
-
The y coordinate of the arc center.
- radius
-
The radius of the arc.
- arc
-
The angle measurement of the arc, specified in degrees.
- startingAngle
-
The starting angle of the arc. The default value is 0.
- radialLines
-
A Boolean value that indicates whether to draw the radial lines that connect the arc to the center. The default is
false. When set totrue, the arc looks like a slice.
The following draws an arc with radial lines; the radius is 50, the arc angle is 80 degrees, and the starting angle is 20 degrees:var pen:Pen = new Pen(graphics); pen.drawArc(100, 100, 50, 80, 20, true);
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Drawing a Rectangle
- InhaltsvorschauYou want to draw a rectangle at runtime.Draw four connecting line segments at right angles. Use the Graphics.drawRect( ) method. For rectangles with rounded corners, use the Graphics.drawRoundRect( ) or Graphics.drawRoundRectComplex( ) method.To draw a simple rectangle, draw four lines using the lineTo( ) method:
// Specify a one-pixel, solid, black line sampleSprite.graphics.lineStyle(1, 0, 100); // Draw four lines to form the perimeter of the rectangle sampleSprite.graphics.lineTo(100, 0); sampleSprite.graphics.lineTo(100, 50); sampleSprite.graphics.lineTo(0, 50); sampleSprite.graphics.lineTo(0, 0);
As you can see, drawing a simple rectangle is no huge feat. However, there are several drawbacks to using the preceding technique of calling lineTo( ) four times. The obvious drawback is that it requires at least five lines of code: one to set the line style and four to draw the line segments. Another drawback is that you cannot easily draw the rectangle at an angle or with rounded corners.You can use the Graphics.drawRect( ) method to simplify drawing a standard rectangle. The method requires four parameters specifying the X and Y coordinates of the upper-left corner and the width and height of the rectangle. The following draws a 100×50 rectangle with the upper-left corner aligned to 0,0:sampleSprite.graphics.lineStyle( ); sampleSprite.graphics.drawRect(0, 0, 100, 50);
The Graphics.drawRoundRect( ) method draws a rectangle with rounded corners with equal radii. The method accepts the same parameter list as drawRect( ) with one additional parameter specifying the value for the corner radii. The following draws the same rectangle as in the preceding example, except that it has rounded corners with radii of 20:sampleSprite.graphics.lineStyle( ); sampleSprite.graphics.drawRoundRect(0, 0, 100, 50, 20);
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Drawing a Circle
- InhaltsvorschauYou want to draw a circle at runtime.Use the Grahics.drawCircle( ) method.Drawing a circle with the standard drawing methods is not as simple as you might think. Because of Flash’s simplified, single control point Bezier calculations, it requires at least eight segments to create a circle that looks convincingly like a circle. Making the calculations in order to draw each segment of the circle requires a fair amount of math and code. However, the Graphics class has a drawCircle( ) method that greatly simplifies drawing a circle. The drawCircle( ) method requires three parameters:
- x
-
The x coordinate of the circle’s center point.
- y
-
The y coordinate of the circle’s center point.
- radius
-
The radius of the circle.
The following draws a circle with a radius of 50 and the center point at100,100:sampleSprite.graphics.lineStyle( ); sampleSprite.graphics.drawCircle(100, 100, 50);
Drawing concentric circles is simple enough; just specify the same center point for the circles:sampleSprite.graphics.lineStyle( ); sampleSprite.graphics.drawCircle(100, 100, 50); sampleSprite.graphics.drawCircle(100, 100, 100);
You can fill a circle by calling beginFill( ), beginGradientFill( ), or beginBitmapFill( ) before drawCircle( ), and calling endFill( ) after drawCircle( ):sampleSprite.graphics.lineStyle( ); sampleSprite.graphics.beginFill(0xFF0000); sampleSprite.graphics.drawCircle(100, 100, 50); sampleSprite.graphics.endFill( );
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Drawing an Ellipse
- InhaltsvorschauYou want to draw an ellipse (oval) at runtime.Use the Pen.drawEllipse( ) method.An ellipse is a more abstract form of a circle. Rather than having a single, uniform radius, an ellipse is defined by two radii that intersect at right angles. The two radii are called the major and minor radii, and also sometimes simply the x radius and y radius.Drawing an ellipse is just slightly more complex than drawing a circle. However, unlike circles, the Graphics class has no method for drawing ellipses. Therefore, the simplest way to programmatically create an ellipse is to use one of the methods of the Pen class. The drawEllipse( ) method allows for the following four parameters:
- x
-
The x coordinate of the center of the ellipse.
- y
-
The y coordinate of the center of the ellipse.
- xRadius
-
The radius of the ellipse in the x direction (major axis).
- yRadius
-
The radius of the ellipse in the y direction (minor axis).
The following code defines a Pen object and then draws an ellipse:var pen:Pen = new Pen(sampleSprite.graphics); pen.drawEllipse(100, 100, 100, 50);
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Drawing a Triangle
- InhaltsvorschauYou want to draw a triangle at runtime.Use the Pen.drawTriangle( ) method.You can determine and plot the vertices of a triangle, given the lengths of two sides and the angle between them. This is a better approach than specifying the lengths of the three sides, because knowing two sides and the angle between them always determines a triangle, whereas three arbitrary sides may not fit together to make a triangle.The calculations involved in drawing a triangle based on two sides and an angle are slightly complex, so the simplest way to programmatically draw a triangle is to use the drawTriangle( ) method of the Pen class. The drawTriangle( ) method accepts up to seven parameters, described as follows:
- x
-
The X coordinate of the centroid (the center point) of the triangle.
- y
-
The Y coordinate of the centroid of the triangle.
- ab
-
The length of the side formed between points a and b.
- ac
-
The length of the side formed between points a and c.
- angle
-
The angle (in degrees) between sides ab and ac.
- rotation
-
The rotation of the triangle in degrees. If 0 or
undefined, side ac parallels the x axis.
Once you’ve defined a Pen instance, you can use the drawTriangle( ) method to quickly draw a triangle, as in the following example:var pen:Pen = new Pen(sampleSprite.graphics); pen.drawTriangle(100, 100, 100, 200, 40);
You can precede drawTriangle( ) with a call toEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Drawing Regular Polygons
- InhaltsvorschauYou want to draw a regular polygon (a polygon where all sides are equal length) at runtime.Use the Pen.drawRegularPolygon( ) method.You can create a method to draw a regular polygon using basic trigonometric ratios to determine the necessary angles and coordinates of the segments. Of course, since employing those trigonometric ratios requires quite a lot of code and you actually recall trigonometry, you’ll likely find it much easier to simply use the drawRegularPolygon( ) method of the Pen class.The drawRegularPolygon( ) accepts up to five parameters, described as follows:
- x
-
The x coordinate of the center of the polygon.
- y
-
The y coordinate of the center of the polygon.
- sides
-
The number of sides in the polygon.
- length
-
The length of each side in pixels.
- rotation
-
The number of degrees by which the polygon should be rotated.
Once you have defined a Pen instance, you can quickly draw regular polygons with any number of sides (with a minimum of three sides, of course, to be a valid polygon):var pen:Pen = new Pen(sampleSprite.graphics); // Draw a pentagon in which the sides are each 50 pixels pen.drawRegularPolygon(100, 100, 5, 50);
As with the other shape drawing methods in this chapter, you can create a filled polygon by invoking beginFill( ), beginGradientFill( ), or beginBitmapFill( ) before drawRegularPolygon( ), and invoking endFill( ) after drawRegularPolygon( ):var pen:Pen = new Pen(sampleSprite.graphics); pen.beginFill(0xFF0000); pen.drawRegularPolygon(100, 100, 5, 50); pen.endFill( );
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Drawing a Star
- InhaltsvorschauYou want to draw a star.Use the Pen.drawStar( ) method.The Pen.drawStar( ) method enables you to quickly draw a star shape programmatically. The method accepts the following parameters:
- x
-
The x coordinate of the center of the star.
- y
-
The y coordinate of the center of the star.
- points
-
The number of points on the star.
- innerRadius
-
The radius of the inner part of the star.
- outerRadius
-
The radius of the outer part of the star.
- rotation
-
The default value is 0; you can specify a rotation in degrees.
The following example draws a five-pointed star:var pen:Pen = new Pen(sampleSprite.graphics); pen.drawStar(100, 100, 5, 50, 100);
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Filling a Shape with a Solid or Translucent Color
- InhaltsvorschauYou want to draw a shape and fill it with a solid or translucent color at runtime.Use the Graphics.beginFill( ) and Graphics.endFill( ) methods to initiate and close a shape drawn at runtime.To draw a filled shape, call beginFill( ) prior to any other drawing methods. Invoke endFill( ) after calling other drawing methods to create the shape.You cannot apply a fill to an existing shape drawn at authoring time or runtime. Before drawing the shape you want filled, you must first invoke the beginFill( ) method.This example creates a solid green square:
sampleSprite.graphics.lineStyle( ); sampleSprite.graphics.beginFill(0x00FF00); sampleSprite.graphics.lineTo(100, 0); sampleSprite.graphics.lineTo(100, 100); sampleSprite.graphics.lineTo(0, 100); sampleSprite.graphics.lineTo(0, 0); sampleSprite.graphics.endFill( );
The MovieClip.beginFill( ) method accepts two parameters:- fillColor
-
The RGB value to use for the fill.
- alpha
-
The value between 0 (transparent) and 1 (opaque) that controls the opacity. The default is 1.
To create a translucent, filled shape, specify an alpha less than 1. If alpha is 0, the shape appears unfilled. However, setting the alpha to 0 is often appropriate. For example, you may want to create a draggable movie clip within which parts are transparent. Setting the fill alphas for those parts to 0 can help to accomplish that.The endFill( ) method does not require any parameters. It simply ends the fill initiated with beginFill( ), beginGradientFill( ), or beginBitmapFill( ). To avoid unexpected results, ensure that the pen returns to the starting point to complete the shape before invokingEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Filling a Shape with a Gradient
- InhaltsvorschauYou want to draw a shape and fill it with a gradient at runtime.Use the beginGradientFill( ) and endFill( ) methods to initiate and close a shape drawn at runtime.A gradient fill is one in which there is a graded change in colors. Flash supports linear gradients, in which one color fades into the next from left to right. (If you want the gradient to change vertically then you can simply rotate the gradient using the matrix transform discussed in this recipe.) Flash also supports radial gradients, in which the colors radiate out from a center point. You can initiate a gradient-filled shape by using beginGradientFill( ) in the same way that you can initiate a solid-filled shape with beginFill( ). The difference is that the call to beginGradientFill( ) requires a more complex set of parameters:
- gradientType
-
One of the constants from the flash.display.GradientType class. The options are
LINEARorRADIAL. - colors
-
An array of RGB values for the colors to use in the gradient. They are displayed in the gradient from left to right in a linear gradient, or from the center outward in a radial gradient.
- alphas
-
An array of alpha values that correspond to the colors in the colors parameter array.
- ratios
-
An array whose elements are numbers corresponding to the colors and alphas elements. The values in the ratios array indicate the point within the gradient at which each color is pure. The range of values for the ratios should be from 0 (left-most point in a linear fill, or inner-most point in a radial fill) to 255 (rightmost or outer-most).
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Filling a Shape with a Bitmap
- InhaltsvorschauYou want to apply a bitmap fill to a shape.Use the Graphics.beginBitmapFill( ) method.The Graphics.beginBitmapFill( ) method enables you to apply a bitmap as a fill to a shape. The method accepts the following parameters:
- bitmap
-
A BitmapData object to use as the bitmap fill.
- matrix
-
By default the bitmap is applied with no transform applied. You can specify a flash.geom.Matrix object to transform the bitmap by scaling, rotating, skewing, and translating the image.
- repeat
-
A Boolean value indicating whether or not the bitmap ought to repeat to tile fill. By default the value is
true. When the value is set tofalsethe bitmap edge’s pixels are repeated to fill the shape. - smooth
-
A Boolean value indicating whether or not to apply smoothing when the bitmap is scaled greater than 100 percent. The default is
false.
The following sample class loads a bitmap from a URL, copies it to a BitmapData object, and uses that BitmapData object as a fill for circles drawn programmatically:package { import flash.display.Sprite; import flash.geom.Matrix; import flash.display.Loader; import flash.net.URLRequest; import flash.display.BitmapData; import flash.events.Event; public class Drawing extends Sprite { private var _loader:Loader; public function Drawing( ) { _loader = new Loader( ); _loader.load(new URLRequest("http://www.rightactionscript.com/samplefiles/image2.jpg")); _loader.contentLoaderInfo.addEventListener(Event.COMPELTE, onImageLoad); } private function onImageLoad(event:Event):void { var bitmap:BitmapData = new BitmapData(_loader.width, _loader.height); bitmap.draw(_loader, new Matrix( )); var matrix:Matrix = new Matrix( ); matrix.scale(.1, .1); var sampleSprite:Sprite = new Sprite( ); sampleSprite.graphics.lineStyle( ); sampleSprite.graphics.beginBitmapFill(bitmap, matrix); sampleSprite.graphics.drawCircle(100, 100, 100); sampleSprite.graphics.endFill( ); addChild(sampleSprite); } } }Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Scripting Masks
- InhaltsvorschauYou want to create a mask at runtime.Use DisplayObject.mask.Masks can be used to create unique shapes or visual effects. For example, you can use masks to create wipes and transitions. You can use masks to create interesting animations in which only the masked portion of the artwork is visible at a given time. You can even create masks that shape tween and use them to mask bitmapped graphics (in movie clips).Any display object can be used as a mask of another display object by using the
maskproperty. The following sets maskSprite as the mask for sampleSprite:sampleSprite.mask = maskSprite;
The following example draws two shapes and uses one as a mask. Note that both display objects are added to the display list via addChild( ). Although masks will work in most cases, even when the mask object isn’t added to the display list, it’s recommended that you add the mask object to the display list:var maskSprite:Sprite = new Sprite( ); var pen:Pen = new Pen(maskSprite.graphics); pen.beginFill(0xFFFFFF); pen.drawArc(100, 100, 50, 80, 20, true); pen.endFill( ); var maskedSprite:Sprite = new Sprite( ); maskedSprite.graphics.lineStyle( ); maskedSprite.graphics.beginFill(0xFF0000); maskedSprite.graphics.drawRect(0, 0, 200, 200); maskedSprite.graphics.endFill( ); maskedSprite.mask = maskSprite; addChild(maskedSprite); addChild(maskSprite);
This next example shows a mask being used to follow the mouse. The mask is assigned to a loader containing a loaded image, which makes it so only the users can see the portion of the image over which they have placed the mouse:var loader:Loader = new Loader( ); loader.load(new URLRequest("http://www.rightactionscript.com/samplefiles/image2.jpg")); addChild(loader); var maskSprite:Sprite = new Sprite( ); maskSprite.graphics.lineStyle( ); maskSprite.graphics.beginFill(0xFFFFFF); maskSprite.graphics.drawCircle(0, 0, 50); maskSprite.graphics.endFill( ); loader.mask = maskSprite; addChild(maskSprite); maskSprite.startDrag(true);Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Chapter 8: Bitmaps
- InhaltsvorschauFlash 8 introduced the BitmapData class, one of the most important additions to the program at that time. Since its inception, Flash has been a vector-based tool. Vector graphics consist of mathematical descriptions of each graphical element. For example, a line starts at point x0, y0 and extends to point x1, y1. A bitmap, on the other hand, describes a graphic as a rectangular grid of values, with one color value assigned to each pixel.The two main advantages of vector graphics are scaling and file size. When you scale a vector graphic, you are actually moving the points that make up the lines and curves of the graphic further apart or closer together. Thus, you can scale up or down to almost any size and still maintain smooth lines and curves. A bitmap, on the other hand, starts to look “blocky” as soon as you increase its size even slightly, since each pixel is simply made into a larger rectangle.Since a vector graphic is nothing more than a list of coordinates that make up various lines, curves, and shapes, the file size tends to be quite low when compared to a bitmap graphic. Bitmap graphics, on the other hand, contain value information for each pixel in the image. For a 100×100-pixel image, this is a list of 10,000 individual values. Of course, most bitmap images use some form of compression to reduce the file size. Even so, they can be quite large.The advantage of vector graphics went a long way to make Flash such a popular media format on the web. However, bitmaps are not without their own advantages. For one, bitmaps are much better at displaying photographic images. The amount of vectors it would take to describe all the shapes and color variations in a photograph would generally result in a larger file size than a bitmap of the same image.Another benefit of bitmaps is that they are often easier on the processor than vectors are. In a vector image, each point’s position must be calculated, and then the formulas for the lines and curves are calculated and drawn. Complex images can take quite a while to render. Bitmaps are relatively easy to render, though, no matter how complex they are. In terms of animation, you usually find very significant gains in speed and efficiency using bitmaps over vectors.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- Introduction
- InhaltsvorschauFlash 8 introduced the BitmapData class, one of the most important additions to the program at that time. Since its inception, Flash has been a vector-based tool. Vector graphics consist of mathematical descriptions of each graphical element. For example, a line starts at point x0, y0 and extends to point x1, y1. A bitmap, on the other hand, describes a graphic as a rectangular grid of values, with one color value assigned to each pixel.The two main advantages of vector graphics are scaling and file size. When you scale a vector graphic, you are actually moving the points that make up the lines and curves of the graphic further apart or closer together. Thus, you can scale up or down to almost any size and still maintain smooth lines and curves. A bitmap, on the other hand, starts to look “blocky” as soon as you increase its size even slightly, since each pixel is simply made into a larger rectangle.Since a vector graphic is nothing more than a list of coordinates that make up various lines, curves, and shapes, the file size tends to be quite low when compared to a bitmap graphic. Bitmap graphics, on the other hand, contain value information for each pixel in the image. For a 100×100-pixel image, this is a list of 10,000 individual values. Of course, most bitmap images use some form of compression to reduce the file size. Even so, they can be quite large.The advantage of vector graphics went a long way to make Flash such a popular media format on the web. However, bitmaps are not without their own advantages. For one, bitmaps are much better at displaying photographic images. The amount of vectors it would take to describe all the shapes and color variations in a photograph would generally result in a larger file size than a bitmap of the same image.Another benefit of bitmaps is that they are often easier on the processor than vectors are. In a vector image, each point’s position must be calculated, and then the formulas for the lines and curves are calculated and drawn. Complex images can take quite a while to render. Bitmaps are relatively easy to render, though, no matter how complex they are. In terms of animation, you usually find very significant gains in speed and efficiency using bitmaps over vectors.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- Creating a BitmapData Object
- InhaltsvorschauYou want to create a new bitmap in your application.Use the BitmapData class’s constructor to create a new BitmapData object.The BitmapData class represents the pixels in a bitmap image, and contains many built-in methods for adding content to and manipulating that image. The first step is to create an instance of the class by calling its constructor, as follows:
var bitmap:BitmapData = new BitmapData(width, height, transparent, fillColor);
This class is part of the flash.display package, so make sure you import flash.display.BitmapData at the top of the file. Thewidthandheightparameters specify what size bitmap you want to create. The next parameter is a Boolean value, which specifies whether the bitmap is created with an alpha channel (true) or not (false), and thefillColordetermines the initial background color of the image.Although width and height are mandatory, transparent and fillColor default totrueand0xFFFFFFFF, respectively if not explicitly passed to the constructor.The fillColor accepts a 32-bit color value, which means that it supports an alpha channel. Of course, the alpha channel of the fill color is only relevant if you create the BitmapData specifyingtransparentastrue. Otherwise, all colors are treated as 100 percent opaque.The following example creates a BitmapData that is initially completely transparent, as the alpha channel of thefillColoris set to zero:var bitmap:BitmapData = new BitmapData(100, 100, true, 0x00FFFFFF);After you create a new BitmapData, it exists only in memory. Although you can create content in the image and manipulate it, it will not be visible until you add it to the display list.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Adding a Bitmap to the Display List
- InhaltsvorschauYou have created a BitmapData and now want to make it visible.Create a Bitmap using the BitmapData and add that to the display list.To make anything visible in an application in ActionScript 3.0, you must add it to the display list. (See Chapter 6 for a full discussion of the display list.) You add objects to the display list by calling the addChild( ) method from the main application class, or any other object that has already been added to the display list. However, the addChild( ) method only accepts objects that are subclasses of flash.display.DisplayObject. The BitmapData class is descended only from Object, so you may not add it to the display list directly.To add it to the display list, use the flash.display.Bitmap class, which is a subclass of DisplayObject. It is a sort of wrapper for BitmapData, allowing a BitmapData to be displayed.When you create a new instance of Bitmap by calling its constructor, you pass in a reference to a BitmapData. Then you can add the Bitmap to the display list using addChild( ). The following example creates a BitmapData with a red fill, and displays it via a Bitmap:
var bitmap:BitmapData = new BitmapData(100, 100, true, 0xffff0000); var image:Bitmap = new Bitmap(bitmap); addChild(image);
Recipe 8.1 for how to create a bitmap.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Drawing a Display Object to a Bitmap
- InhaltsvorschauYou have some graphical content in a sprite or other display object and want to draw that to a bitmap.Use the BitmapData class’s draw( ) method to draw the content onto the bitmap.When you first create a BitmapData, it is simply a blank rectangle of whatever color you specified. You may have some existing graphic content in a movie clip, sprite, or other display object that you would like to draw to the new bitmap. The draw( ) method allows you to do just this. You pass the object you want to draw into the draw( ) method of the BitmapData you want to draw it onto. You can also pass an instance of the flash.geom.Matrix class to the method. The Matrix class allows you to scale, rotate, translate, or skew the object’s graphics before they are drawn. This parameter is optional, but if you need to use later parameters and don’t want to transform the object, just pass null. You can also optionally pass a ColorTransform object, which alters the color of the object before it is drawn. See Recipe 10.1 for information on ColorTransforms. The following example draws a sprite, named
_sprite, into a BitmapData namedbitmap, with no transformation:bitmap.draw(_sprite);
One reason why this becomes important is because the BitmapData class has few tools for basic drawing. You can set a pixel to a particular color, create a filled rectangle, or do a flood fill. There are some specialized noise functions, but it lacks basic functions such as line, curve, oval, or outline drawing tools. To overcome this, you can use the drawing API methods to draw content into a movie clip or sprite, and then draw that object into the bitmap. The following example creates a BitmapData and a Sprite. It then uses the drawing API to draw an oval in the sprite and draws the sprite into theEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Loading an External Image into a Bitmap
- InhaltsvorschauYou want to load an external bitmap image and manipulate it as a BitmapData.Use the flash.display.Loader class to load the image. When the image has loaded, access the loader’s content property, which is a Bitmap. Accessing that Bitmap’s bitmapData property gives you direct access to the BitmapData representing the loaded image.You load an external bitmap image via the Loader class. This takes a URLRequest object with the URL of the image you are loading. Listening for the loader’s complete event lets you know when the image has loaded. Here is the setup to create the loader—listen for the complete event and begin loading an image:
package { import flash.display.Sprite; import flash.display.Loader; import flash.events.Event; import flash.net.URLRequest; public class BitmapLoader extends Sprite { private var _loader:Loader = new Loader( ); public function BitmapLoader( ) { _loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete); _loader.load(new URLRequest("image.jpg")); } } }By itself, this code simply loads and displays the specified image. Next, create theonCompletemethod that accesses the bitmap information once it has loaded:public function onComplete(event:Event):void { var image:Bitmap = Bitmap(_loader.content); var bitmap:BitmapData = image.bitmapData; addChild(image); }First, get a reference to the loader’s content property. This is a display object representing the content that was loaded. If you have loaded an external .swf, it is a MovieClip type. In this case, however, you have loaded a bitmap image, so the content contains a Bitmap. You should cast it as a Bitmap so the compiler doesn’t complain when you try to access properties that belong only toEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Manipulating Pixels
- InhaltsvorschauYou want to set or read the value of individual pixels in a bitmap.Use the getPixel( ), setPixel( ), getPixel32( ), and setPixel32( ) methods of the BitmapData class.Setting and reading pixel values of a bitmap is relatively straightforward in ActionScript 3.0. To read the value of a pixel, just pass in the x, y coordinates of the pixel you want to read to one of the getPixel methods. To set a pixel’s color, pass in the coordinates and the color value to one of the setPixel methods.The getPixel( ) and setPixel( ) methods are designed for use on opaque BitmapData instances, while getPixel32( ) and setPixel32( ) are used on images that support transparency. Opaque images are 24-bit, with 8 bits for each of its red, green, and blue channels. Transparent images add another 8-bit alpha channel for a total of 32 bits. You specify whether the BitmapData supports transparency or not in its constructor. See Recipe 8.1.The following code creates a white, 32-bit BitmapData, and then sets 1,000 random pixels to a semi-transparent red color:
var bitmap:BitmapData = new BitmapData(100, 100, true, 0xffffffff); var image:Bitmap = new Bitmap(bitmap); addChild(image); for(var i:int = 0; i < 1000; i++) { bitmap.setPixel32(Math.round(Math.random( ) * 100), Math.round(Math.random( ) * 100), 0x88ff0000); }If you use setPixel( ) on a transparent BitmapData, the alpha channel is set to 100 percent opaque for that pixel, even if you specify something else. Similarly, if you use setPixel32( ) on an opaque image, the alpha channel data is ignored, as such an image does not have an alpha channel. In general, it is best to use the correct pair of methods for the type of bitmap you are working with.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Creating Rectangular Fills
- InhaltsvorschauYou want to fill a rectangular area of a bitmap with a color.Use the fillRect( ) method of the BitmapData class.The BitmapData class does not have the wealth of drawing tools available in the drawing API for movie clips and sprites. It does have a basic rectangle fill tool, though. Using this method is quite simple. Just pass in the rectangle area you want to fill and the color value with which you want to fill it:
_bitmap.fillRect(rectangle, color);
The rectangle must be an instance of the flash.geom.Rectangle class. You can make an instance of the class by calling its constructor with the x, y, width, and height of the rectangle you want to create, as so:var rect:Rectangle = new Rectangle(0, 0, 50, 100);
The following code creates a white bitmap, and then draws a red square in the middle of it:public function RectExample( ) { _bitmap = new BitmapData(100, 100, false, 0xffffffff); var image:Bitmap = new Bitmap(_bitmap); addChild(image); _bitmap.fillRect(new Rectangle(25, 25, 50, 50), 0xffff0000); }Note that there is only one version of fillRect( ) for both transparent and non-transparent images. If you are using it with an image that does not have an alpha channel, just pass a 24-bit color value, as the extra bits for alpha are ignored anyway. If you are using it with a transparent image, be sure to use a full 32-bit number. If you just pass a 24-bit value, the alpha channel is set at 0 percent alpha.Recipes 8.5, 8.7, 8.8, 8.9, 8.10, and 8.11 for other ways to add graphical content to a bitmap.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Creating a Flood Fill
- InhaltsvorschauYou want to fill a large area, possibly irregular, with a color.Use the floodFill( ) method of the BitmapData class.The floodFill( ) method has the same syntax as the setPixel( ) method. That is, you pass it an x, y coordinate and a color. The method colors that pixel and any surrounding pixels the same color. This is the same as the bucket tool in most graphics programs, such as Adobe Photoshop.The following code demonstrates it in action. It first creates a bitmap and a number of random squares and then sets up a
mouseDownhandler that performs a flood fill on the selected pixel:package { import flash.display.Sprite; import flash.display.Bitmap; import flash.display.BitmapData; import flash.events.MouseEvent; import flash.geom.Rectangle; public class FloodFillDemo extends Sprite { private var _bitmap:BitmapData; public function FloodFillDemo ( ) { var sprite:Sprite = new Sprite( ); addChild(sprite); _bitmap = new BitmapData(stage.stageWidth, stage.stageHeight, false, 0xffffffff); for(var i:int = 0; i < 20; i++) { _bitmap.fillRect(new Rectangle( Math.random( ) * stage.stageWidth, Math.random( ) * stage.stageHeight, 50, 50), Math.random( ) * 0xffffffff); } var image:Bitmap = new Bitmap(_bitmap); sprite.addChild(image); sprite.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); } public function onMouseDown(event:MouseEvent):void { _bitmap.floodFill(mouseX, mouseY, 0xffff0000); } } }Recipes 8.5, 8.6, 8.8, 8.9, 8.10, and 8.11 for other ways to add graphical content to a bitmap.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Copying Pixels
- InhaltsvorschauYou want to copy a rectangular area from one BitmapData to another.Use the copyPixels( ) method of the BitmapData class.The theory behind the copyPixels( ) method is quite simple. It takes the pixel data from one bitmap and draws it onto another. In that sense, it is much like the draw( ) method. However, in the case of copyPixels( ), you get more control over how much of the bitmap is copied and where it is copied to. You do this by specifying a source rectangle and a destination point:
bitmap.copyPixels(sourceBmp, srcRect, destPoint);
The source rectangle is an instance of the flash.geom.Rectangle class. You use this to define a rectangular area of the original BitmapData. This is the only portion of that bitmap that is copied.The destination point is an instance of flash.geom.Point. This specifies the x, y coordinate of the destination bitmap where you want to paste the copied pixels.The following example shows how to copy several rectangular areas of a loaded bitmap onto another BitmapData:package { import flash.display.Sprite; import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Loader; import flash.net.URLRequest; import flash.events.Event; import flash.geom.Point; import flash.geom.Rectangle; public class AS3CB extends Sprite { private var _bitmap:BitmapData; private var _loader:Loader; public function AS3CB( ) { _loader = new Loader( ); _loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoad); _loader.load(new URLRequest("myphoto.jpg")); _bitmap = new BitmapData(stage.stageWidth, stage.stageHeight, false, 0xffffffff); var image:Bitmap = new Bitmap(_bitmap); addChild(image); } public function onLoad(event:Event):void { var loaderBmp:Bitmap = Bitmap(_loader.content); var w:Number = loaderBmp.width / 10; for(var i:int = 0; i < 10; i++) { _bitmap.copyPixels(loaderBmp.bitmapData, new Rectangle(i * w, 0, w, loaderBmp.height), new Point(i * (w + 2), i)); } } } }Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Copying Channels
- InhaltsvorschauYou want to copy the red, green, blue, or alpha from one BitmapData to another.Use the copyChannel( ) method of the BitmapData class.The copyChannel( ) method is yet another method that draws information from one bitmap to another. Actually, the first three arguments are the same as the copyPixels( ) method. In addition, it has source channel and destination channel parameters:
bitmap.copyPixels(sourceBmp, srcRect, destPoint, srcChannel, destChannel);The two channel parameters can be one of the integers 1, 2, 4, or 8, which represent the red, green, blue, and alpha channels, respectively. Rather than risking a typographical error, you should use the static properties of the BitmapDataChannel class:RED,GREEN,BLUE, andALPHA.You simply tell the method which channel you want to take from the original image and which channel you want to copy it into in the destination image. The following code copies the red, green, and blue channels of a loaded image to a new bitmap, slightly offset from one another:var loaderBmp:Bitmap = Bitmap(loader.content); bitmap.copyChannel(loaderBmp.bitmapData, loaderBmp.bitmapData.rect, new Point( ), BitmapDataChannel.RED, BitmapDataChannel.RED); bitmap.copyChannel(loaderBmp.bitmapData, loaderBmp.bitmapData.rect, new Point(5, 5), BitmapDataChannel.GREEN, BitmapDataChannel.GREEN); bitmap.copyChannel(loaderBmp.bitmapData, loaderBmp.bitmapData.rect, new Point(10, 10), BitmapDataChannel.BLUE, BitmapDataChannel.BLUE);Recipes 8.5, 8.6, 8.7, 8.8, 8.10, and 8.11 for other ways to add graphical content to a bitmap.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Creating Noise
- InhaltsvorschauYou want to create a random noise pattern in a bitmap.Use the noise( ) method of the BitmapData class.A noise filter or pattern is simply sets each pixel in an affected area to a random value. Although you could loop through each pixel in a bitmap and use setPixel( ) to randomly change its color, there is an easier and more powerful way of doing the same thing in one line: the noise( ) method.By itself, noise( ) creates a random, speckled image, like what you see when a television is tuned to a channel with no signal. However, by combining noise with other filters, such as the blur filter, you can get some very useful effects.The noise( ) method is called directly on an instance of BitmapData, and its parameters are straightforward:
bitmap.noise(seed, low, high, channel, grayscale);
Use the seed parameter to determine the random pattern; it can be any integer. If you call the method twice with the same seed, you get the same noise pattern. To ensure you get a different pattern each time you call it, pass in a random number like so:Math.random( ) * 100000
Thelowandhighparameters determine the minimum and maximum values for each pixel. They can range from 0 to 255. Setting them higher gives you a brighter noise pattern; setting them lower makes darker noise.Thechannelparameter specifies to which color channel of the bitmap the noise will be applied. You can specify 1, 2, 4, or 8 for red, green, blue, and alpha, respectively; or use the static properties of the BitmapDataChannel class:RED,GREEN,BLUE, andALPHA, to guard against typos.Finally,grayscaleis a Boolean value.trueapplies the random value to the three color channels equally, resulting in a colorless noise.Here are some examples. First, create a bitmap, add the noise, and then display it:Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Creating Perlin Noise
- InhaltsvorschauYou want to create random organic effects, such as clouds, smoke, or water.Use the perlinNoise( ) method of the BitmapData class.Like the noise( ) method, perlinNoise( ) creates random patterns on a bitmap. However, Perlin noise uses an algorithm that produces smooth, organic-looking textures. It was created by Ken Perlin for creating textures in the movie Tron. These textures are perfect for use as explosions, smoke, water, and many other natural-looking effects, and since they are generated by an algorithm, they require much less memory than bitmap-based textures. The usage is as follows:
bitmap.perlinNoise(baseX, baseY, octaves, seed, stitch, fractal, channels, grayscale, offsets);The first six parameters are necessary; the final three are optional. Since there are so many parameters to consider, let’s create a simple example and then see what each one does. The following code creates a bitmap, applies Perlin noise to it and then displays it:bitmap = new BitmapData(stage.stageWidth, stage.stageHeight, false, 0xff000000); bitmap.perlinNoise(100, 100, 1, 1000, false, false, 1, true, null); var image:Bitmap = new Bitmap(bitmap); addChild(image);
Add this code to a new class, and run it to see a simple Perlin noise pattern. See Figure 8-1 for an example of what you should see. Now you can start changing parameters and see what effect the changes have.First off,baseXandbaseYdetermine the size of the pattern. Here they are set to 100 each. Try changingbaseXto 200 andbaseYto 50 and see how that stretches out the noise horizontally. Already you can see that it looks a bit like rippling water, as you can see in Figure 8-2.
Figure 8-1: Simple Perlin noiseEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Using Threshold
- InhaltsvorschauYou want to change the value of some pixels in a bitmap, based on their current value.Use the threshold( ) method of the BitmapData class.The threshold( ) method is probably the most complex in the BitmapData API, but quite powerful once you understand how it works. The method uses two BitmapData objects:
-
destBitmap, which is the bitmap that will be altered. -
sourceBitmap, which is the other bitmap that gets passed in as a parameter. The method uses this bitmap’s pixel data for its calculations.
The method compares each pixel insourceBitmapagainst a specified value, using one of six comparison operators. If the comparison fails, the corresponding pixel indestBitmapis set to a specified color value. If it passes the comparison, the pixel is either not changed, or you have the option of copying over thesourceBitmap’s value for that pixel.Here is the syntax for the method:destBitmap.threshold(sourceBitmap, sourceRect, destPoint, operation, threshold, color, mask, copySource)We’ve already covereddestBitmapandsourceBitmap. The next parameter,sourceRect, is an instance of the flash.geom.Rectangle class. It defines what portion of thesourceBitmapyou want to use for comparison. If you want to use the entire bitmap, you can pass insourceBitmap.rectas a value to this parameter.ThedestPointparameter specifies the point in thedestBitmapat which the pixels start to be affected. Picture thesourceBitmapoverlaid ondestBitmap, with its top-left corner on this point. If you want to use 0, 0 as the origin, just passEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Applying a Filter to a Bitmap
- InhaltsvorschauYou want to apply a filter to a BitmapData.Use the applyFilter( ) method of the BitmapData class, or add a filter to the filters array of the enclosing Bitmap.As mentioned, there are two methods of applying a filter to a bitmap. The first method is to use the applyFilter( ) method directly on the BitmapData itself. Like some of the other BitmapData methods, this method is applied to one BitmapData, which is the destination bitmap, and it can take another BitmapData as a source bitmap:
destBmp.applyFilter(srcBmp, sourceRect, destPoint, filter);
-
The
srcBmpis the bitmap file you want to apply the filter to. -
The
sourceRectis the specific rectangular area from the source bitmap that you want to apply the filter to. -
The
destPointparameter specifies the upper lefthand point from which the pixels will be affected in the destination bitmap. -
The
filter, of course, is an instance of the BitmapFilter that you want to apply.
You can, of course, apply a filter using the same bitmap as both source and destination. Doing so is considered “destructive,” not because it’s a bad thing but because it permanently changes the bitmap.The values of each pixel are calculated based on the original content and the filter parameters, and these values overwrite the original pixel data. This is useful in a couple of instances:-
If you are sure you will never need to change either the bitmap’s content or the filter itself.
-
When you have multiple or repeated applications of a filter.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Dissolving Between Two Bitmaps
- InhaltsvorschauYou want to fade between one bitmap and another.Use the pixelDissolve( ) method of the BitmapData class.Like many of the other BitmapData methods, pixelDissolve( ) uses a source and destination bitmap. Each time it is called, it copies a specified number of random pixels from the source bitmap to the destination. To complete a full dissolve, call this method repeatedly, either in an enterFrame handler or a timer-based function. See Recipe 11.1 for information on timer-based animation.The first time the pixelDissolve( ) method is called, you pass it a random number to use as a seed for the first round of pixel copying. It returns a number that you should keep track of and use as the seed for the next iteration.Here is the syntax for the method:
seed = srcBmp.pixelDissolve(destBmp, sourceRect, destPoint, seed, numPixels, fillColor);
-
The sourceRect and destPoint parameters work the same way they do in other BitmapData methods that use two bitmaps. The seed is explained more in Recipe 8.10.
-
The numPixels parameter determines how many pixels are copied each time the method is called.
-
The fillColor offers an easy way of fading a single bitmap to a specified color. If you use the same BitmapData as source and destination, instead of copying identical pixels from one to the other (which would have no visible effect), the chosen pixels are set to the fill color specified in this parameter. You can ignore this when using two different bitmaps.
The first example uses two bitmaps—one white, one black—and dissolves between them at 1,000 pixels per frame:Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Scrolling a Bitmap
- InhaltsvorschauYou want to scroll the content of a BitmapData.Use the scroll( ) method of the BitmapData class.The operation and syntax is simple and straightforward. You pass the amounts you want to scroll the bitmap’s content on the X- and Y-axes:
_bitmap.scroll(xAmount, yAmount);
The method effectively copies the pixels in the bitmap and pastes them back, offset by the amount specified. Any pixels that aren’t overwritten in the operation remain the same as they were originally.You can call scroll( ) repeatedly in an enterFrame handler or timer function to animate the scrolling of the bitmap. The following code demonstrates this by generating a Perlin noise pattern and then scrolling it:public function Scroll( ) { _bitmap = new BitmapData(stage.stageWidth, stage.stageHeight, false, 0xffffffff); _bitmap.perlinNoise(100, 100, 3, 1000, true, true, 1, true); _image = new Bitmap(_bitmap); addChild(_image); addEventListener(Event.ENTER_FRAME, onEnterFrame); } public function onEnterFrame(event:Event):void { _bitmap.scroll(-1, -1); }Note that the edges that are not copied in the scroll are not cleared, but left as they were.Recipes 8.12, 8.13, and 8.14 for other ways to manipulate the content in a bitmap.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Chapter 9: Text
- InhaltsvorschauThe flash.text.TextField class is the way in which all text is displayed in Flash Player. Even the text components such as TextArea and TextInput use the TextField class to display text. Flash Player enables a great deal of functionality for text fields from enabling user input to embedding fonts to using Cascading Style Sheets (CSS) to format text. In this chapter, we’ll discuss all the many things you can accomplish with text.As implied in the preceding paragraph, the TextField class is packaged in the flash.display package. Therefore, you need to either import the class or refer to the class with the fully qualified class name. All examples in this chapter assume you’ve imported the class with the following line of code:
import flash.text.TextField;
ActionScript 3.0 uses a display list that is quite different from previous versions of ActionScript. With earlier versions of ActionScript, you construct a text field using the TextField constructor as follows:createTextField( );
However, with ActionScript 3.0, the new text field object isn’t automatically added to the display list. That means that if you want to make the text field visible, you have to use the addChild( ) method. As discussed in Chapter 6, the addChild( ) method is defined for all container display objects, such as Sprite, and it adds the object specified as a parameter to the display list of the object from which it is called. For example, the following line of code adds the field TextField object to the display list of the instance of the TextExample class:package { import flash.display.Sprite; import flash.text.TextField; public class TextExample extends Sprite { public function TextExample( ) { var field:TextField = new TextField( ); addChild(field); } } }When the examples in this chapter reference an object calledfield, it’s frequently assumed that the object is aEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Introduction
- InhaltsvorschauThe flash.text.TextField class is the way in which all text is displayed in Flash Player. Even the text components such as TextArea and TextInput use the TextField class to display text. Flash Player enables a great deal of functionality for text fields from enabling user input to embedding fonts to using Cascading Style Sheets (CSS) to format text. In this chapter, we’ll discuss all the many things you can accomplish with text.As implied in the preceding paragraph, the TextField class is packaged in the flash.display package. Therefore, you need to either import the class or refer to the class with the fully qualified class name. All examples in this chapter assume you’ve imported the class with the following line of code:
import flash.text.TextField;
ActionScript 3.0 uses a display list that is quite different from previous versions of ActionScript. With earlier versions of ActionScript, you construct a text field using the TextField constructor as follows:createTextField( );
However, with ActionScript 3.0, the new text field object isn’t automatically added to the display list. That means that if you want to make the text field visible, you have to use the addChild( ) method. As discussed in Chapter 6, the addChild( ) method is defined for all container display objects, such as Sprite, and it adds the object specified as a parameter to the display list of the object from which it is called. For example, the following line of code adds the field TextField object to the display list of the instance of the TextExample class:package { import flash.display.Sprite; import flash.text.TextField; public class TextExample extends Sprite { public function TextExample( ) { var field:TextField = new TextField( ); addChild(field); } } }When the examples in this chapter reference an object calledfield, it’s frequently assumed that the object is aEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Creating an Outline Around a Text Field
- InhaltsvorschauYou want to place a border around a text field.Set the text field’s
borderproperty totrue. Additionally, you can change the color of the border by setting the object’sborderColorproperty.By default, a text field does not have a visible border, which is assumed to be the most common preferred behavior. For example, you may not want a border around an item label. However, there are many cases in which you will want to apply a border to a text field, such as a field that requires some user input. The border shows the user where to click to input a value. Simply setting a text field’sborderproperty totrueturns on the border around the object:field.border = true;
To turn off the border, simply set theborderproperty tofalse.The default border color is black, but that can be changed with theborderColorproperty, which accepts a hex RGB value corresponding to the desired color:field.borderColor = 0xFF00FF; // Make the border violet.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Creating a Background for a Text Field
- InhaltsvorschauYou want to make a visible background behind the text in a text field.Set the text field’s
backgroundproperty totrue. Additionally, you can change the color of the background by setting the object’sbackgroundColorproperty.By default, text fields don’t have a visible background. However, you can create a background for a text field by setting thebackgroundproperty for that object totrue:field.background = true;
By default, the background for a text field is white (if made visible). You can, however, assign the background color by setting the value of the object’sbackgroundColorproperty, which accepts a hex RGB value corresponding to the desired color, as shown here:field.backgroundColor = 0x00FFFF; // Set the background to light blue
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Making a User Input Field
- InhaltsvorschauYou want to create a user input field to allow the user to enter text.Set the text field’s
typeproperty to TextFieldType.INPUT.There are two types of text fields: dynamic and input. The default text field type is dynamic. This means that it can be controlled with ActionScript, but the user cannot input text into it. To enable the field for user input, set thetypeproperty to theINPUTconstant of the flash.display.TextFieldType class:field.type = TextFieldType.INPUT;
Though it isn’t a requirement, input fields generally also have a border and a background. Otherwise, the user might find it difficult to locate and select the field:field.border = true; field.background = true;
For a user to be able to input text, the field’sselectableproperty must betrue, which is the default. You don’t need to set theselectableproperty totrue, unless you previously set it tofalse.If you have previously defined an input text field that you want to make a dynamic text field (so that it does not accept user input) you can set the type property to theDYNAMICconstant of the flash.display.TextFieldType class:field.type = TextFieldType.DYNAMIC;
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Making a Password Input Field
- InhaltsvorschauYou want to create a password-style text field that hides the characters as asterisks. You also want to disable copying from the text field.Set the text field’s
passwordproperty totrue.When a user enters a password into a field, you generally want to make it so others aren’t able to read the password. This is a basic security precaution. The common convention is to display only asterisks in the field as the user types. This way, the user can see that she is successfully entering a value without anyone else being able to easily read what she’s just typed.To create an input field that is automatically masked with asterisks, you only need to set the TextField.passwordproperty totrue:field.password = true;
When you set the password property totrue, all text entered into the text field, either programmatically or by user input, displays as asterisks:field.password = true; field.text = "example text"; // Text field displays: ************
Password text fields also disable copying from the text field. That prevents a user from being able to copy passwords or similar data and then paste it into a plain text document.Password text fields are most commonly also input text fields; however, you can set the password property totruefor a dynamic text field as well.Although password text fields hide the data from the display, they do not encrypt the data or make it more secure for sending over a network. If data security is important to your application, you must use technologies that make data secure as it is transferred over a network. If you send data from Flash using standard HTTP, then the data is sent in an unsecured fashion. Use a technology such as SSL if you must send data in a secure fashion.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Filtering Text Input
- InhaltsvorschauYou want to restrict the characters that a user can type into an input field.Set the
restrictproperty of the text field.By default, a user can type any character into an input field. However, in many scenarios, you might want to restrict the allowable characters. For example, you might restrict characters to numbers and dashes in the case of an input field for telephone numbers.The TextField.restrictproperty lets you specify the allowed characters for user input into a field. Specify a string containing the allowable characters, such as:field.restrict = "abcdefg";
This example lets the user enter any of the allowable characters: a, b, c, d, e, f, or g. Other characters are disallowed. If the user tries to enter grabs, only gab appears, since the letters r and s are not in the allowable character set.If therestrictstring is set to the empty string then all characters are allowed. To prevent input entirely, set thetypetoDYNAMIC.Also, note that ActionScript distinguishes between upper- and lowercase characters. In other words, there is a difference between a and A. If therestrictproperty is set to abcdefg, the uppercase variants of the allowable characters (such as A, B, C) will be entered as the lowercase (allowable) equivalents (a, b, c). The same is true in reverse, such that if a lowercase character is entered when only the uppercase counterpart is allowed, the character is converted to uppercase.Therestrictproperty supports certain regular expression-like patterns. Therefore, you can also enter ranges by indicating the first character in the range and the last character in the range separated by a dash (-):field.restrict = "a-zA-Z"; // Allow only upper- and lowercase letters field.restrict = "a-zA-Z "; // Allow only letters and spaces field.restrict = "0-9"; // Allow only numbers
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Setting a Field’s Maximum Length
- InhaltsvorschauYou want to limit the length of the string input into a text field.Set the text field’s
maxCharsproperty.By default, an input text field allows a user to type in as many characters as he desires. However, you may have good reason to want to set a maximum. For example, if an input field prompts a user for his two-character country code, you might want to prevent the user from entering more than two characters. Setting themaxCharsproperty to a number limits the user input to that many characters:field.maxChars = 6; // maximum of 6 characters can be input
SetmaxCharstonullto allow an entry of unlimited length, if you’ve previously assigned a non-null value tomaxChars.Recipe 9.5Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Displaying Text
- InhaltsvorschauYou want to display text within a text field.Set the
textproperty of a text field.Aside from being used as input fields, text fields are often used to display text to the user. Setting a text field’stextproperty causes the corresponding text to display in the field:field.text = "this will display in the field";
Special characters, such as\\tfor tab and\\nfor newline, can be used within a text string.You can append text by using the+=operator or the appendText( ) method:field.appendText("new text");Recipe 9.8 for information on support for HTML-formatted text.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Displaying HTML-Formatted Text
- InhaltsvorschauYou want to display HTML content in a text field.Set the text field’s
htmlTextproperty to the value of the HTML content to display.Text fields can interpret and display basic HTML tags, if properly configured. Using HTML in a text field is a convenient way to add hyperlinks and simple formatting, such as font color and bolded text.The value of the text field object’shtmlTextproperty is interpreted as HTML:field.htmlText = "<u>This displays as underlined text.</u>";
No matter what, thetextproperty of a text field is rendered as plain text. This means that even if thetextproperty is set to<u>test</u>, the object displays<u>test</u>instead of test. That means that if you want to display HTML code in its unrendered format assign the HTML value to thetextproperty of the text field, as follows:field.text = "<u>underlined text</u>"; /* text field displays: <u>underlined text</u> */
This can be a useful technique if, for example, you want to show both the rendered HTML and the HTML source code in side-by-side text fields:htmlCode = "<i>italicized text</i>"; sourceHTML.text = htmlCode; renderedHTML.htmlText = htmlCode;
You cannot display both rendered and unrendered HTML in the same text field. If you try, you will end up with unreliable results.The set of HTML tags supported by text fields includes:<b>,<i>,<u>,<font>(withface,size, andcolorattributes),<p>,< br>,<a >,<li>,<img>, and<textformat>(withleftmargin,rightmargin,blockindent,indent,leading, andtabstopsattributes corresponding to the TextFormat class’s properties of the same names).Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Condensing Whitespace
- InhaltsvorschauYou want to condense whitespace in an HTML text field display.Set the object’s
condenseWhiteproperty totrue.When you use HTML in a text field, the optionalcondenseWhitesetting condenses whitespace, as is done in most HTML browsers. For example, the following text would be rendered in a web browser with only a single space between “hello” and “friend” in spite of the fact that the original source has multiple spaces between the two words.hello friend
In ActionScript text fields, however, all of the spaces are displayed, unless you set thecondenseWhiteproperty totrue:field.condenseWhite = true; field.htmlText = "hello friend"; // Displays: "hello friend"
ThecondenseWhiteproperty works only when thehtmlproperty istrue.Recipe 9.8Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Sizing Text Fields to Fit Contents
- InhaltsvorschauYou want to size a text field’s viewable area to fit the text it contains.Use the
autoSizeproperty.You can set theautoSizeproperty of a text field so it automatically resizes itself in order to fit its contents. The possible values forautoSizeare theRIGHT,LEFT,CENTER, andNONEconstants of the flash.text.TextFieldAutoSize class. By default,autoSizeis set toNONE, meaning that the text field does not automatically resize.Set the property toLEFTif you want the text field to resize while fixing the upper-left corner’s position. In other words, the text field’s lower-right corner is the point that moves when it expands and contracts:// These two lines do the same thing field.autoSize = TextFieldAutoSize.LEFT; field.autoSize = true;
Set the property toCENTERif you want the text field to be anchored at its center point. While the top of the object remains fixed, it expands and contracts downward and equally to the right and left:field.autoSize = TextFieldAutoSize.CENTER;
Set the property toRIGHTif you want the upper-right corner of the text field to remain steady while the object expands and contracts in the direction of the lower-left corner:field.autoSize = TextFieldAutoSize.RIGHT;
When wordWrap is set tofalse(the default), then the text field expands horizontally to accommodate the text. In such a case, the text field expands vertically only if there are newlines within the text assigned to the text field. The following example illustrates a text field that auto sizes to accommodate all the text on one line:var field:TextField = new TextField( ); field.autoSize = TextFieldAutoSize.LEFT; field.text = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi tortor purus, aliquet a, ornare ac, suscipit a, est. Nullam hendrerit molestie erat. Nunc nulla tortor, ullamcorper et, elementum vel, fringilla sed, dui. Praesent fermentum interdum orci."; addChild(field);
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Scrolling Text Programmatically
- InhaltsvorschauYou want to scroll text in a text field via ActionScript.Use the
scrollV,maxScrollV,bottomScrollV,scrollH, andmaxScrollHproperties of the text field. Use themouseWheelEnabledproperty to enable scrolling of text by way of the mouse wheel.You can control the scrolling of a text field with ActionScript and without the aid of a scrollbar. For example, you may want to scroll the contents of a text field automatically to display a word or selection within the text. You can programmatically control a text field’s scrolling in both the vertical and horizontal directions using some built-in properties. You should use thescrollV,maxScrollV, andbottomScrollVproperties to control vertical scrolling, and use thescrollHandmaxScrollHproperties to control horizontal scrolling.Every text field has a number of lines, whether it is 1 or 100. Each of these lines is identified by a number starting at 1. Some of these lines may be visible, and some may be beyond the border of the text field. Therefore, to view the lines that extend beyond the visible portion of the text field you must scroll to them. Figure 9-1 illustrates this point. It depicts a text field’s display where the solid line indicates the object’s border (the visible area), and the dotted line surrounds the rest of the text contained within the object but lying outside the its visible area. To the left of the text field are line numbers for each line of text. The three labels—scrollV,bottomScrollV, andmaxScrollV—indicate the meaning of the text field properties of the same names.
Figure 9-1: Understanding scrollV, bottomScrollV, and maxScrollVThescrollVproperty is a read-write property that indicates the top line of the text field’s visible area. In Figure 9-1, theEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Responding to Scroll Events
- InhaltsvorschauYou want to have some actions performed when a text field’s contents are scrolled.Listen for the scroll event.When a text field is scrolled vertically or horizontally (meaning that the
scrollVorscrollHproperty has been changed either by your custom ActionScript code or a scrollbar), the text field dispatches a scroll event. The scroll event name is defined by theSCROLLconstant of the flash.events.Event class, and the event that is dispatched is a flash.events.Event object. The following code registers a listener for the scroll event for a text field calledfield:field.addEventListener(Event.SCROLL, onTextScroll);
The following defines an example onTextScroll( ) method that listens for the scroll event:private function onTextScroll(event:Event):void { trace("scroll"); }Recipes 9.23 and 9.24Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Formatting Text
- InhaltsvorschauYou want to format the text in a text field.Use HTML tags, pass a TextFormat object to the TextField.setTextFormat( ) method, or use a StyleSheet object, and apply it to the text field’s
styleSheetproperty.Although you can set the color of the entire contents of the text field using thetextColorproperty, for example, the TextField class doesn’t offer precise control over character formatting. However, there are several ways in which you can apply more exacting formatting to text fields:-
Use HTML tags to apply formatting. For example, you can use
<font>,<b>, and<u>tags. -
Use a TextFormat object.
-
Use CSS.
Each of the three ways in which you can apply formatting to a text field has its own advantages and disadvantages. Applying HTML formatting is relatively simple, but it is the most difficult to manage of the different techniques. Using a TextFormat object is the more complex than applying formatting via HTML. However, when you want to apply complex formatting, it is a better option than HTML formatting. Using CSS with a StyleSheet object allows the greatest flexibility, and it allows you to load a CSS document, which makes it simple to maintain because you can edit the CSS document without having to re-export the .swf file.For fast and simple formatting, HTML tags are simplest. For example, the following code displays bolded and underlined text:field.html = true; field.htmlText = "<b>Bold text</b> <u>Underlined text</u>";
You can use TextFormat objects to apply more complex formatting to the text displayed in text fields. The first step in formatting text with a TextFormat object is to instantiate the object by using the constructor method:Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Formatting User-Input Text
- InhaltsvorschauYou want to apply formatting to text as the user enters it into a text field.Apply a TextFormat object by using the defaultTextFormat property of the text field.You should use the defaultTextFormat property of a text field object to apply text formatting to text as it is entered by user input. Create a TextFormat object as in Recipe 9.13, and then assign that object to the text field’s defaultTextFormat property:
var formatter:TextFormat = new TextFormat( ); formatter.color = 0x0000FF; // Make the text blue field.defaultTextFormat = formatter;
When you use defaultTextFormat, the formatting is applied to text that the user types into the field.Recipes 9.13 and 9.15Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Formatting a Portion of Existing Text
- InhaltsvorschauYou want to add formatting to some, but not all, text in a text field, or you want to apply different formatting to various parts of a text field.Create a TextFormat object and use it to format a substring of the text field by using one of the setTextFormat( ) method variations.You can format an entire text field as shown in Recipe 9.13, or you can use one of the versions of the setTextFormat( ) method to format just a portion of a text field. These variations allow you to apply formatting to the specified character range only.You can set the formatting for a single character within a text field by invoking the setTextFormat( ) method and passing it two parameters:
- index
-
The zero-relative index of the character to which the formatting should be applied.
- textFormat
-
A reference to a TextFormat object.
This example applies the formatting to the first character only:field.setTextFormat(0, formatter);
Alternatively, if you want to apply the formatting to a range of characters, you can invoke setTextFormat( ) with three parameters:- startIndex
-
The beginning, zero-relative character index.
- endIndex
-
The index of the character after the last character in the desired range.
- textFormat
-
A reference to a TextFormat object.
This example applies the formatting to the first 10 characters:field.setTextFormat(0, 10, formatter);
You may notice that when you try to format portions of a text field, certain formatting options do not get applied under certain circumstances. For example, text alignment is applied only if the formatti ng is applied to the first character in the line.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Setting a Text Field’s Font
- InhaltsvorschauYou want to use ActionScript to change the font used for some displayed text.Use a
<font>tag in HTML, set thefontproperty of a TextFormat object, or use thefont-familyproperty in CSS.You can programmatically specify the font that is used to display text by using one of several different options. You can use a<font>tag if you are applying the formatting using HTML. For example:field.htmlText = "<font face='Arial'>Formatted text</font>";
You can also use thefontproperty of a TextFormat object. You can assign to this property the string name of the font (or fonts) that should be used:formatter.font = "Arial";
And you can also define a font-family property in CSS:p { font-family: Arial; }The font specified must be available on the computer on which the movie is running. Because some computers may not have the preferred font installed, you can specify multiple font names separated by commas, as follows:formatter.font = "Arial, Verdana, Helvetica";
The preceding example uses a TextFormat object. However, you can specify a comma-delimited list of fonts by using any of the techniques described.The first font is used unless it cannot be found, in which case the Flash Player attempts to use the next font in the list.If none of the specified fonts are found, the default system font is used. You can optionally specify a font group. Font groups use the default device font within a category. A font group is often preferable to allowing Flash Player to use the default system font, since at least you’ll know what general characteristics the font will have. There are three font groups: _sans, _serif, and _typewriter. The _sans group is generally a font such as Arial or Helvetica, theEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Embedding Fonts
- InhaltsvorschauYou want to ensure that text displays properly, even if the intended font isn’t installed on the user’s computer.Embed the font by using the
[Embed]metatag. Then set the text field’sembedFontsproperty totrue, and apply the font to the text field using a<font>tag, a TextFormat object, or CSS.You should embed fonts if you want to ensure that text displays using the intended font, even if the user’s computer does not have that font installed. To embed a font, use the[Embed]metatag. The[Embed]metatag should appear in an ActionScript file outside the class declaration. You can embed either TrueType fonts or system fonts. To embed a TrueType font with the[Embed]metatag use the following syntax:[Embed(source="pathToTtfFile", fontName="FontName", mimeType="application/x-font-truetype")]
The path to the TrueType font file can be relative or absolute, such as in the following example:[Embed(source="C:\\Windows\\Fonts\\Example.ttf", fontName="ExampleFont", mimeType="application/x-font-truetype")]
The fontName attribute value is how you refer to the font from CSS or ActionScript.The syntax for embedding system fonts is similar, except that it uses a systemFont attribute rather than a source attribute. The systemFont attribute value is the name of the system font you want to embed. The following embeds Times New Roman:[Embed(systemFont="Times New Roman", fontName="Times New Roman", mimeType="application/x-font-truetype")]
The preceding example uses the same name for fontName as the actual system font name.Once you’ve embedded the font, the next step is to tell the text field to use the embedded font. To do that, simply set theembedFontsproperty of the text field totrue. By default, the property isEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Creating Text that Can Be Rotated
- InhaltsvorschauYou want to make sure that some text continues to display, even when it’s rotated.Use embedded fonts.Unless you specifically use an embedded font, text fields use device fonts. For most situations, this is perfectly workable. However, in situations in which you want to rotate a text field or its parent container (e.g., you want to place a label next to an object vertically), you must use embedded fonts. Device fonts disappear when rotating a text field.Recipe 9.17 explains how to embed fonts.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- Displaying Unicode Text
- InhaltsvorschauYou want to display Unicode text in your application, possibly including non-English characters.Load the text from an external source. Optionally, use Unicode escape sequences for the characters within the assignment to the text field’s
textproperty.If you want to display Unicode text in a text field, there are several ways in which you can accomplish that:-
Load the Unicode text from an external source (e.g., a text file, XML document, database).
-
Use the character directly within the ActionScript code as a string value.
-
Use a Unicode escape sequence.
If you load the text from an external source, you can load Unicode text and assign it to a text field. For more information regarding loading content from external sources, see Chapter 20.Assuming you’re using an editor that supports Unicode (such as Flex Builder), you can add the character directly within the code. Optionally, if you know the escape sequence for the character, you can assign it to a text field’stextproperty. All Unicode escape sequences in ActionScript begin with\\uand are followed by a four-digit hexadecimal number. The escape sequences must be enclosed in quotes. The following example displays a registered mark (®) in both ways:field.text = "Add a registered mark directly (®) or with a Unicode escape sequence (\\u00AE)";
If you want a Unicode character reference online, under Windows, you can open up the Character Map utility using Start → Programs → Accessories → System Tools → Character Map. On Mac OS X, first enable the Input Menu in System Preferences → International → Input Menu, and turn on the checkbox next to Character Palette. To open the Character Palette, go to the menu bar, select the flag for your country (e.g., the Stars and Stripes for the U.S.), and select Show Character Palette.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Assigning Focus to a Text Field
- InhaltsvorschauYou want to use ActionScript to bring focus to a text field.Use the Stage.focus property.Use the Stage.focus property to programmatically assign focus to a specific text field. Every display object has a stage property that references the Stage instance. Therefore, from a class that extends a display object class (Sprite, MovieClip, etc.) the following code assigns focus to a text field called field:
stage.focus = field;
When an .swf first loads in a web browser, it does not have focus. Therefore, you must move focus to the Flash Player before you can programmatically assign focus to an element of the Flash application. The following is a working example that uses a sprite button to assign focus to a text field:package { import flash.display.Sprite; import flash.text.TextField; import flash.text.TextFieldType; import flash.events.MouseEvent; public class TextExample extends Sprite { public function TextExample( ) { var field:TextField = new TextField( ); field.border = true; field.background = true; field.type = TextFieldType.INPUT; addChild(field); var button:Sprite = new Sprite( ); button.graphics.lineStyle( ); button.graphics.beginFill(0xFFFFFF); button.graphics.drawRect(0, 0, 100, 50); button.graphics.endFill( ); button.addEventListener(MouseEvent.CLICK, onClick); button.y = 100; addChild(button); } private function onClick(event:MouseEvent):void { stage.focus = TextField(getChildAt(0)); } } }To remove focus from a text field you should assign Stage.focus thenullvalue:stage.focus = null;
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Selecting Text with ActionScript
- InhaltsvorschauYou want to highlight a portion of the text within a text field.Use the TextField.setSelection( ) method.The TextField.setSelection( ) method highlights a portion of the text in the text field. The setSelection( ) method takes two parameters:
- startIndex
-
The beginning, zero-relative index of the text to highlight.
- endIndex
-
The index of the character after the text to highlight.
For the selection to work, the text field must have focus, which you can set by using Stage.focus, as discussed in Recipe 9.20:stage.focus = field; // Set the focus to the text field field.text = "this is example text"; // Set the text value field.setSelection(0, 4); // Highlight the word "this"
Use the read-onlyselectionBeginIndexandselectionEndIndexproperties to retrieve the indices of the selected character range.Recipes 9.20 and 9.23Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Setting the Insertion Point in a Text Field
- InhaltsvorschauYou want ActionScript to set the insertion point for a text field.Use the TextField.setSelection( ) method.You can use TextField.setSelection( ) to set the cursor position in a text field by setting the beginning and ending index parameters to the same value. This example sets the cursor position in the text field, assuming it has focus:
// Positions the insertion point before the first character field.setSelection(0, 0);
You can retrieve the index of the cursor position with the read-only caretIndex property:trace(field.caretIndex);
Recipe 9.21Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Responding When Text Is Selected or Deselected
- InhaltsvorschauYou want to perform a task when a text field is selected or deselected.Listen for the focusIn and focusOut events.Text fields dispatch focusIn events when focus is shifted to the field and they dispatch focusOut events when focus is shifted away from the field. The events dispatched in both cases are flash.events.FocusEvent objects. The FocusEvent class defines a relatedObject property. In the case of focusIn events, the relatedObject property is a reference to the object that just had focus. In the case of focusOut events, the relatedObject property is a reference to the object that just received focus. Use the flash.events.FocusEvent constants of
FOCUS_INandFOCUS_OUTwhen registering listeners:field.addEventListener(FocusEvent.FOCUS_IN, onFocus);
The focusIn and focusOut events both occur after the focus has already changed. They are non-cancelable events. If you want to be able to cancel the events, you must listen for events that occur before focusIn and focusOut are dispatched. The keyFocusChange and mouseFocusChange events are cancelable events that occur when the user attempts to move focus from a text field by way of the keyboard or mouse, respectively. You can register listeners by using the FocusEvent constants ofKEY_FOCUS_CHANGEandMOUSE_FOCUS_CHANGE. Use the FocusEvent.preventDefault( ) method to cancel the default behavior. The following example disallows using the Tab key to move fromfield1tofield2iffield1doesn’t have any text:package { import flash.display.Sprite; import flash.text.TextField; import flash.text.TextFieldType; import flash.events.FocusEvent; public class Text extends Sprite { private var _field1:TextField; private var _field2:TextField; public function Text( ) { _field1 = new TextField( ); _field1.border = true; _field1.background = true; _field1.type = TextFieldType.INPUT; addChild(_field1); _field1.addEventListener(FocusEvent.KEY_FOCUS_CHANGE, onKeyFocus); _field2 = new TextField( ); _field2.border = true; _field2.background = true; _field2.type = TextFieldType.INPUT; addChild(_field2); _field2.y = 100; } private function onKeyFocus(event:FocusEvent):void { if(_field1.text == "") { event.preventDefault( ); } } } }Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Responding to User Text Entry
- InhaltsvorschauYou want to perform a task when the content of a text field is modified by user input.Listen for the textInput event.You can specify actions to be performed each time the content of a text field is changed by user input, whether that change is deleting or cutting characters, typing in a character, or pasting characters. When a user makes any change to the value of an input text field, the text field dispatches a textInput event. You can register a listener to listen for the textInput event using the flash.events.TextEvent.TEXT_INPUT constant:
field.addEventListener(TextEvent.TEXT_INPUT, onTextInput);
The textInput event is a TextEvent object, and it is cancelable. The TextEvent class defines a text property, which contains the value of the text entered by the user. The following example ensures that the first character the user types in a text field is not an “a”:package { import flash.display.Sprite; import flash.text.TextField; import flash.text.TextFieldType; import flash.events.TextEvent; import flash.events.TextEvent; public class Text extends Sprite { private var _field:TextField; public function Text( ) { _field = new TextField( ); _field.border = true; _field.background = true; _field.type = TextFieldType.INPUT; addChild(_field); _field.addEventListener(TextEvent.TEXT_INPUT, onTextInput); } private function onTextInput(event:TextEvent):void { if(event.text == "a" && _field.length == 0) { event.preventDefault( ); } } } }Recipe 9.12Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Adding a Hyperlink to Text
- InhaltsvorschauYou want to hyperlink some of the text displayed in a text field.Use HTML
<a href>tags within the object’shtmlTextproperty. Alternatively, use a TextFormat object with a value assigned to theurlproperty.Both solutions to this problem require that you set the text field’shtmlproperty totrue:field.html = true;
If you want to use HTML to add a hyperlink, add an<a href>tag to the text field’shtmlTextproperty, as follows:field.htmlText = "<a href='http://www.rightactionscript.com'>Website</a>";
You can add a target window into which to open the link by adding atargetattribute to the<a href>HTML tag. For example:field.htmlText = "<a href='http://www.rightactionscript.com' target='blank'>Website</a>";
When text is hyperlinked in Flash, the mouse cursor changes to a hand when it is over the linked text. Flash does not inherently provide any indication that the text is linked, unlike most HTML browsers (which use an underline and color change). For this reason, it is helpful to add HTML markup that underlines and colors the linked text:var htmlLink:String = "<font color='#0000FF'><u>"; htmlLink += "<a href='http://www.rightactionscript.com'>Website</a>"; htmlLink += "</u></font>"; field.htmlText = htmlLink;
You can accomplish the same tasks without HTML by using a TextFormat object. The TextFormat class includes aurlproperty for just this purpose. Assigning the URL to theurlproperty links the formatted text; for example:field.text = "Website"; var formatter:TextFormat = new TextFormat( ); formatter.url = "http://www.rightactionscript.com/"; field.setTextFormat(formatter);
If you want to specify a target window into which the link opens, you can set the value of the TextFormat object’stargetproperty, as follows:Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Calling ActionScript from Hyperlinks
- InhaltsvorschauYou want to call an ActionScript method when the user clicks a hyperlink.Use the event protocol and listen for link events.Many applications require calling ActionScript when the user clicks a hyperlink. With ActionScript 3.0, however, it is a very simple task. First, you must define the hyperlink to use the event protocol, as follows:
field.htmlText = "<a href='event:http://www.rightactionscript.com'>Website</a>";
When you use the event protocol, the default behavior does not occur. When the user clicks on a hyperlink, it normally opens the URL in a web browser. However, when you use the event protocol, an event is dispatched, which means you have to register a listener to listen for that event. The event type is link, and you can use the flash.events.TextEvent.LINK constant when registering a listener:field.addEventListener(TextEvent.LINK, onClickHyperlink);
The event that is dispatched is a flash.events.TextEvent type. The text property of the event object contains the value of thehrefattribute minus the event protocol. That means that in the preceding example, the value of the event object’s text property is http://www.rightactionscript.com. Since the hyperlink does not attempt to open a URL in a browser window when using the event protocol, you don’t have to use a valid URL for thehrefvalue. You can use any string that would be useful in determining which hyperlink the user clicked.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Working with Advanced Text Layout
- InhaltsvorschauYou want to work with advanced text layout.Use the numLines property and the getCharBoundaries( ), getCharIndexAtPoint( ), getFirstCharInParagraph( ), getLineIndexAtPoint( ), getLineIndexOfChar( ), getLine- Length( ), getLineMetrics( ), getLineOffset( ), getLineText( ), and getParagraphLength( ) methods.In versions of Flash Player up to and including Flash Player 8, it was difficult to control and read text layout with much precision. Starting with Flash Player 8.5, though, the TextField class defines an API for more precise reading of text layout.The TextField class defines two methods for retrieving information about characters from text. The getCharBoundaries( ) method returns a flash.geom.Rectangle object that defines the boundaries of the character at the index specified by the parameter. The getCharIndexAtPoint( ) method returns the index of a character at the x and y coordinates specified by the parameters. The following example uses getCharIndexAtPoint( ) and getCharBoundaries( ) to highlight a character when the user clicks on it:
package { import flash.display.Sprite; import flash.text.TextField; import flash.events.MouseEvent; import flash.geom.Rectangle; public class Text extends Sprite { private var _field:TextField; private var _highlight:Sprite; public function Text( ) { _field = new TextField( ); _field.border = true; _field.background = true; _field.multiline = true; _field.wordWrap = true; _field.selectable = false; _field.width = 400; _field.height = 400; addChild(_field); _field.text = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi tortor purus, aliquet a, ornare ac, suscipit a, est. Nullam hendrerit molestie erat. Nunc nulla tortor, ullamcorper et, elementum vel, fringilla sed, dui. Praesent fermentum interdum orci."; _field.addEventListener(MouseEvent.CLICK, onClick); _highlight = new Sprite( ); addChild(_highlight); } private function onClick(event:MouseEvent):void { var index:int = _field.getCharIndexAtPoint(mouseX, mouseY); var rectangle:Rectangle = _field.getCharBoundaries(index); _highlight.graphics.clear( ); _highlight.graphics.lineStyle(0, 0, 0); _highlight.graphics.beginFill(0x00FFFF, .25); _highlight.graphics.drawRect(rectangle.x, rectangle.y, rectangle.width, rectangle.height); _highlight.graphics.endFill( ); } } }Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Applying Advanced Anti-Aliasing
- InhaltsvorschauYou want to have more precise control over anti-aliasing of text.Embed the font, set the antiAliasType property of the text field to flash.text.AntiAliasType.ADVANCED, and set the gridTypeFit and sharpness properties.By default, text displays with normal anti-aliasing settings. For most fonts at sizes 10 and higher the normal anti-aliasing settings make for legible text. However, for smaller font sizes and for certain fonts, the normal anti-aliasing settings make the text less than legible. In those cases, you can set the anti-alias type for the text field to advanced and use the gridFitType and sharpness properties to more precisely control how the text is rendered.To enable advanced anti-alias settings for a text field, you must use embedded fonts. See Recipe 9.17 for more details on how to embed fonts.The TextField.antiAliasType property accepts one of the flash.text.AntiAliasType constants of
NORMAL(default) orADVANCED. Set the value of the property toADVANCEDfor a text field if you want to enable more precise anti-alias settings:field.antiAliasType = AntiAliasType.ADVANCED;
The gridFitType property determines how the font outlines snap to whole pixels on the screen. The possible values are theNONE,PIXEL, andSUBPIXELconstants of the flash.text.GridFitType class. The default value ofNONEmeans that the text does not snap to whole pixels. That can cause text to appear blurry at smaller font sizes. ThePIXELsetting snaps horizontal and vertical lines of the font outlines to whole pixels on the screen. ThePIXELsetting works only when text is left-aligned. If you want center- or right-aligned text to snap to pixels, use theSUBPIXELsetting.field.gridFitType = GridTypeFit.PIXEL;
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Replacing Text
- InhaltsvorschauYou want to replace text.Use the replaceSelectedText( ) method to replace the highlighted text and replaceText( ) to replace a range of text.The replaceSelectedText( ) method enables you to replace the selected text in a text field. Simply pass the method the string to use as the replacement text. For the method to work, the text field must have focus:
_field.replaceSelectedText("new text");Use the replaceText( ) method to replace text within a text string given a starting and ending index. The following replaces the text from index 100 to index 150, with the new string specified by the third parameter:_field.replaceText(100, 150, "new text");
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Retrieving a List of System Fonts
- InhaltsvorschauYou want to retrieve a list of fonts on the user’s system.Use the static TextField.fontList property.When you want to use system fonts (rather than embedding the font or using a font group), first determine which fonts the user has installed. You can retrieve an array of system fonts on the user’s computer with the TextField.fontList property.
trace(TextField.fontList);
Retrieving the list of available system fonts simply yields an array of strings. To apply a font to the text, you’ll have to use one of the techniques discussed in Recipe 9.16.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Chapter 10: Filters and Transforms
- InhaltsvorschauActionScript lets you to apply several different transforms and filters to display objects (and bitmaps) to change their color, shape, rotation, size, and to apply special effects. Transforms are changes in color, shape, rotation, and size. The remainder of special effects di scussed in this chapter use filters. Filters are native to Flash Player; they allow you to apply effects ranging from blurs to embossing.You want to apply a color to a display object.Assign a flash.geom.ColorTransform object to the display object’s transform.colorTransform property.Every display object has a transform.colorTransform property. The colorTransform property is a flash.geom.ColorTransform object that determines which color transforms are applied to the object. The
colorTransformproperty always returns a copy of the actual ColorTransform object applied to the display object. That means that you cannot directly change the properties of the colorTransform property. You can, however, retrieve a copy of the actual ColorTransform object by assigning the value from the colorTransform property to a variable. Then you can change the properties of that copy and reassign it to the colorTransform property, as shown in the following example:var color:ColorTransform = sampleSprite.transform.colorTransform; color.rgb = 0xFFFFFF; sampleSprite.transform.colorTransform = color;
The ColorTransform class defines two ways to change the solid color that is applied to a display object. You can set the value of thergbproperty, as in the preceding example. Thergbproperty expects a uint value. Generally it’s convenient to specify the value in hexadecimal representation (0xRRGGBB), as in the preceding example. You can also set theredOffset,greenOffsetEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Introduction
- InhaltsvorschauActionScript lets you to apply several different transforms and filters to display objects (and bitmaps) to change their color, shape, rotation, size, and to apply special effects. Transforms are changes in color, shape, rotation, and size. The remainder of special effects di scussed in this chapter use filters. Filters are native to Flash Player; they allow you to apply effects ranging from blurs to embossing.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- Applying Color Changes
- InhaltsvorschauYou want to apply a color to a display object.Assign a flash.geom.ColorTransform object to the display object’s transform.colorTransform property.Every display object has a transform.colorTransform property. The colorTransform property is a flash.geom.ColorTransform object that determines which color transforms are applied to the object. The
colorTransformproperty always returns a copy of the actual ColorTransform object applied to the display object. That means that you cannot directly change the properties of the colorTransform property. You can, however, retrieve a copy of the actual ColorTransform object by assigning the value from the colorTransform property to a variable. Then you can change the properties of that copy and reassign it to the colorTransform property, as shown in the following example:var color:ColorTransform = sampleSprite.transform.colorTransform; color.rgb = 0xFFFFFF; sampleSprite.transform.colorTransform = color;
The ColorTransform class defines two ways to change the solid color that is applied to a display object. You can set the value of thergbproperty, as in the preceding example. Thergbproperty expects a uint value. Generally it’s convenient to specify the value in hexadecimal representation (0xRRGGBB), as in the preceding example. You can also set theredOffset,greenOffset,blueOffset, andalphaOffsetproperties to work with each of the offsets individually. The offset values can range from -255 to 255:var color:ColorTransform = sampleSprite.transform.colorTransform; color.redOffset = 255; color.greenOffset = 255; color.blueOffset = 255; sampleSprite.transform.colorTransform = color;
The preceding code sets each offset for a color transform to 255 to create a white fill effect, and it then applies that transform toEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Applying Color Tints
- InhaltsvorschauYou want to apply a tint to a display object rather than a solid color.Work with the transform.colorTransform property of the display object. However, change the values of the multiplier properties rather than the offset properties.Recipe 10.1 shows how to apply solid colors to display objects. When you apply a solid color to a display object, it causes any contrast within the display object artwork to be indistinguishable. Applying a solid color is essentially the same as applying a fill to the entire shape of the display object. That means that every pixel within the display object is assigned the same color value.When you apply a tint, each pixel’s color is changed relative to the original pixel color value, which means the contrast is maintained. You can apply a tint to a display object in much the same way a solid color is applied. Both use the transform.col orTransform property of the object. The difference is that when you apply a tint, you want to set the offset properties to 0 (the default values) and change the values of the multiplier properties.The multiplier properties (
redMultiplier,greenMultiplier,blueMultiplier, andalphaMultiplier) have valid ranges from 0 to 1. The multiplier values determine how much of the red, green, blue, and alpha components of the original pixel color value to display. The default value for the multiplier properties is 1, which means that by default each pixel displays at 100 percent of the red, green, blue, and alpha components of the original pixel value. The following makes a display object appear with a green tint by keeping thegreenMultiplierat 1 and setting theredMultiplierandblueMultiplierproperties to 0:var color:ColorTransform = sampleSprite.transform.colorTransform; color.redMultiplier = 0; color.blueMultiplier = 0; sampleSprite.transform.colorTransform = color;
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Resetting Color
- InhaltsvorschauYou want to reset the color of a display object back to the default.Assign a new ColorTransform object with default values to the
transform.colorTransform property of the display object.The default values of a flash.geom.ColorTransform object will reset the color of a display object. You can construct a ColorTransform object with default values by calling the constructor with no parameters. The following example resets the color settings forsampleSprite:sampleSprite.transform.colorTransform = new ColorTransform( );
Recipes 10.1 and 10.2Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Shearing
- InhaltsvorschauYou want to shear (skew) a display object.Create a Matrix object with default values, without the
bandcproperties. Thebandcproperties control the y and x shearing, respectively. Assign the Matrix object to the transform.matrix property of the display object.Shearing (or skewing) fixes a point on a plane and translates all the pixels on one side of the point in one direction and all the pixels on the opposite side equally in the opposite direction. The effect is that a rectangle becomes a parallelogram.The flash.geom.Matrix class definesa,b,c,d,tx, andtyproperties. Thebandcproperties determine how much skewing is applied (whereasaandddetermine the scale factor andtxandtydetermine thexandytranslation). Thebproperty determines skewing along the y axis, and thecproperty determines skewing along the x axis. The default values for thebandcproperties are 0. The greater the values, the greater the skewing is down and to the right. Negative values skew the object up and to the left. The following code draws a square and skews it into a parallelogram along the y axis. The Matrix object uses the default values for the properties, except forb, which is assigned a non-default value of 1. (The default values area=1,b=0,c=0,d=1,tx=0, andty=0.)var box:Sprite = new Sprite( ); box.graphics.lineStyle( ); box.graphics.drawRect(0, 0, 100, 100); addChild(box); box.transform.matrix = new Matrix(1, 1, 0, 1, 0, 0);
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Applying Basic Filters
- InhaltsvorschauYou want to apply basic filters such as drop shadows, blurs, glows, and bevels.Construct a new filter object and assign it to the filters array of a display object.The flash.filters package contains the following basic filter classes: DropShadowFilter, BlurFilter, GlowFilter, BevelFilter, GradientGlowFilter, and GradientBevelFilter. We distinguish the preceding list as basic filters because they don’t require additional display objects to apply as part of surface mapping or matrices to apply for complex transforms. Each of the basic filter classes consist of fairly straightforward properties that have straightforward effects on the display objects to which the filters are applied. For example, the DropShadowFilter class allows you to change the drop shadow offset, color, and the amount of blur applied to the shadow by way of properties (and parameters passed to the constructor).Since basic filters are discussed in the Flash and Flex documentation, we won’t discuss unnecessary details of how to construct and change the basic properties of those classes.Once you’ve constructed a filter object, you can apply it to a display object by using the object’s filters property. The filters property is an array of filter objects. The following applies a drop shadow to a display object called
sampleSprite:sampleSprite.filters = [new DropShadowFilter( )];
When you assign an array of filters to the filters property of a display object, the array is copied rather than referenced. That means that any changes to the array or the filters in the array won’t have an effect on the display object until it has been reassigned, as shown in the following example:var dropShadow:DropShadowFilter = new DropShadowFilter( ); var sampleFilters:Array = [dropShadow]; // Applies the drop shadow. sampleSprite.filters = sampleFilters; // Change the color of the drop shadow to white. However, since the actual filter // applied to sampleSprite is a copy of dropShadow this doesn't have an effect // on sampleSprite. dropShadow.color = 0xFFFFFF; // Add a glow filter to the array. However, since the array assigned to sampleSprite // is a copy of sampleFilters there is no effect on sampleSprite. sampleFilters.push(new GlowFilter( )); // Reassign sampleFilters to the filters property of sampleSprite. Now the updates // to the drop shadow and the array (the addition of the glow filter) affect the // display object. sampleSprite.filters = sampleFilters;
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Applying Advanced Filter Effects (Emboss, etc.)
- InhaltsvorschauYou want to apply an advanced filter effect, such as embossing, edge detection, etc.Use a ConvolutionFilter object.The flash.filters.ConvolutionFilter class allows you to apply many effects ranging from brightness and contrast changes to more dramatic effects such as embossing, blurring, edge detection, and sharpening.The convolution filters require an array of values that define a matrix to apply, so you can map each pixel to a new bitmap surface by combining adjacent pixel values. (The actual linear mathematics used are beyond the scope of this book.) The ConvolutionFilter class simplifies the application of such effects so you don’t need to know matrix multiplication or how to apply the pixel mapping. Instead, all you need to know are the basics of the effects of the array of matrix values.The ConvolutionFilter constructor defines all default values for parameters. However, once an effect is applied, you’ll need to define nondefault values for at least the first three parameters. The first two parameters define the dimensions of the matrix, and the third parameter is an array of the matrix values.The first parameter defines the number of columns, and the second parameter defines the number of rows. The following is an example matrix with four columns and two rows:
1 2 3 4 5 6 7 8
Although you can define matrices with nearly any dimension, all the effects discussed in this book require square matrices (matrices with equal numbers of rows and columns).The values for the third parameter (the array of matrix values) are specified from left to right and from top to bottom. For example, the preceding matrix example could be described with the following array:[1, 2, 3, 4, 5, 6, 7, 8]
A square matrix with a 1 in the center surrounded by zeros has a neutral effect. The following code example applies such a matrix to a display object; the matrix would cause no noticeable effect:Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Embossing
- InhaltsvorschauYou want to emboss a display object.Apply a convolution filter with an emboss matrix.An emboss effect causes the edges of a surface to appear raised or recessed. A emboss matrix has a positive value in the center with values on the left and the opposite values on the right arranged in a symmetrical pattern. They determine the amount of embossing applied. The greater the value, the more embossing is applied. The values on the top and bottom of the center column determine whether the embossing causes a raised or raised effect, and they also need to be symmetrical. The following describes a generic emboss matrix:
a d -c b e -b c -d -a
The following is an example of a basic emboss matrix:-1 1 1 -1 1 1 -1 -1 1
The following 3×3 matrix defines a good general purpose emboss effect when applied with a convolution filter:-2 -1 0 -1 1 1 0 1 2
The following example applies the preceding emboss effect to a display object. Note that a divisor isn’t necessary, since the values are symmetrical and the center value is 1:sampleSprite.filters = [new ConvolutionFilter(3, 3, [-2, -1, 0, -1, 1, 1, 0, 1, 2])];
Recipe 10.6Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Detecting Edges
- InhaltsvorschauYou want to detect the edges of a display object.Use an edge detection matrix with a convolution filter.To apply an edge detection effect with a convolution filter, use a matrix with a negative value in the center surrounded by a symmetrical set of positive values, as described in the following generic matrix:
a b c d e d c b a
The following matrix applies a generic edge detection effect:0 1 0 1 -3 1 0 1 0
The following applies the preceding edge detection effect to a display object:sampleSprite.filters = [new ConvolutionFilter(3, 3, [0, 1, 0, 1, -3, 1, 0, 1, 0])];
The greater the center number, the less edge detection is applied. The following uses a center value of -1 with a divisor:sampleSprite.filters = [new ConvolutionFilter(3, 3, [0, 1, 0, 1, -1, 1, 0, 1, 0], 3)];
Recipe 10.6Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Sharpening
- InhaltsvorschauYou want to apply a sharpening effect to a display object.Use a sharpening matrix and apply it with a convolution filter.You can sharpen an object by using a matrix very similar to the structure of the matrix that detects edges. The only difference is that with an edge detection matrix the center value is negative surrounded by positive values; the sharpen matrix, instead uses a positive center value surrounded by negative values. The following example sharpens a display object:
sampleSprite.filter = [new ConvolutionFilter(3, 3, [0, -1, 0, -1, 5, -1, 0, -1, 0])];
You can apply a less dramatic sharpen effect by increasing the center value and using a divisor:sampleSprite.filter = [new ConvolutionFilter(3, 3, [0, -1, 0, -1, 10, -1, 0, -1, 0], 5)];
You can apply a more dramatic sharpen effect by decreasing the center value and either increasing the surrounding values or using a divisor:sampleSprite.filter = [new ConvolutionFilter(3, 3, [0, -1, 0, -1, 1, -1, 0, -1, 0], -3)];
Recipe 10.6Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Making a Digital Negative
- InhaltsvorschauYou want to make a digital negative from a display object.Use a digital negative matrix and apply it with a ColorMatrixFilter object.You can use a digital negative matrix in conjunction with a flash.filters.ColorMatrixFilter object to apply the matrix. The digital negative matrix is as follows:
-1 0 0 0 255 0 -1 0 0 255 0 0 -1 0 255 0 0 0 1 0
The following example applies a digital negative effect to a display object:sampleSprite.filters = [new ColorMatrixFilter([-1, 0, 0, 0, 255, 0, -1, 0, 0, 255, 0, 0, -1, 0, 255, 0, 0, 0, 1, 0])];
You can also use theascb.filters.ColorMatrixArrays.DIGITAL_NEGATIVEconstant, as shown here:sampleSprite.filters = [new ColorMatrixFilter(ColorMatrixArrays.DIGITAL_NEGATIVE)];
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Applying Grayscale
- InhaltsvorschauYou want to apply a grayscale effect.Use a grayscale matrix, and apply it using a ColorMatrixFilter object.You can apply a grayscale effect by converting all colors to their luminance equivalents. A simplified, nontechnical definition of luminance is the measure of brightness. You can convert a color to the equivalent luminance by multiplying the colors by the red, green, and blue luminance constants. The constants used for computer graphics differ from the NTSC standard used for broadcast purposes. The computer graphics luminance constants are 0.3086, 0.694, and 0.0820, respectively, for the RGB values. The following matrix describes a grayscale effect:
0.3086 0.6094 0.0820 0 0 0.3086 0.6094 0.0820 0 0 0.3086 0.6094 0.0820 0 0 0 0 0 1 0
The following applies a grayscale effect to a display object:sampleSprite.filters = [new ColorMatrixFilter([0.3086, 0.6094, 0.0820, 0, 0, 0.3086, 0.6094, 0.0820, 0, 0, 0.3086, 0.6094, 0.0820, 0, 0, 0, 0, 0, 1, 0])];
You can use theascb.filters.ColorMatrixArrays.GRAYSCALEconstant:sampleSprite.filters = [new ColorMatrixFilter(ColorMatrixArrays.GRAYSCALE)];
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Changing Saturation
- InhaltsvorschauYou want to change the saturation of a display object.Use a saturation matrix and apply it with a ColorMatrixFilter object.You can affect saturation with the following matrix:
a b c 0 0 d e f 0 0 g h i 0 0 0 0 0 1 0
In the preceding matrix, you need to determine the values ofathroughiwith the following equations, wherered,blue, andgreenare the luminance constants andvalueis the saturation value:a = (1 – value) * red + value b = (1 – value) * green c = (1 – value) * blue d = (1 – value) * red e = (1 – value) * green + value f = (1 – value) * blue g = (1 – value) * red h = (1 – value) * green i = (1 – value) * blue + value
When the saturation value is 0, the matrix is a grayscale matrix.You can use the ascb.filters.ColorMatrixArrays.getSaturationArray( ) method to construct a saturation matrix array, given just the value.sampleSprite.filters = [new ColorMatrixFilter(ColorMatrixArrays.getSaturationArray(2))];
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Changing Brightness
- InhaltsvorschauYou want to change the brightness of a display object.Use a matrix, and apply it using a ColorMatrixFilter objects. Optionally, you can change brightness using a ConvolutionFilter object.You can adjust the brightness using a ColorMatrixFilter object by passing it a matrix that scales or offsets the red, green, and blue equally. The following matrix is a general representation of a matrix that scales the red, green, and blue equally:
a 0 0 0 0 0 a 0 0 0 0 0 a 0 0 0 0 0 1 0
The following matrix offsets the red, green, and blue values equally:1 0 0 0 a 0 1 0 0 a 0 0 1 0 a 0 0 0 1 0
The following example increases the brightness of a display object by scaling the colors to twice their original values:sampleSprite.filters = [new ColorMatrixFilter([2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0])];
You can also adjust brightness with a ConvolutionFilter object, as mentioned in Recipe 10.6.Recipe 10.6Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Changing Contrast
- InhaltsvorschauYou want to adjust the contrast of a display object.Use a contrast matrix and apply it with a ColorMatrixFilter object.As mentioned in Recipe 10.13, you can adjust the brightness by either scaling or offsetting color values. You can change contrast by both scaling and offsetting color values at the same time. The following matrix describes a generic contrast matrix:
a 0 0 0 b 0 a 0 0 b 0 0 a 0 b 0 0 0 1 0
You can calculate the scale and offset values from one contrast value by using the following equations:a = value * 11 b = 63.5 – (value * 698.5)
You can use the ascb.filters.ColorMatrixArrays.getContrastArray( ) method to construct a contrast array given the contrast value. The effective range for the contrast value is from 0 to 1:sampleSprite.filters = [new ColorMatrixFilter(ColorMatrixArrays.getContrastArray(1))];
Recipe 10.13Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Chapter 11: Programmatic Animation
- InhaltsvorschauAnimation can be defined as any visual change over time. If an image does not change over a period of time, it’s impossible to tell whether it is a still image or an animation. There are a variety of properties you can manipulate to produce change, and thus animation. The most obvious is changing an object’s position to make it move. You can also change its size, shape, rotation, transparency or color, to name a few. As long as something changes visually, the viewer never sees the animation.In the earliest versions of Flash, most animation was done by using tweens. An object was placed on a keyframe, another keyframe was made, and the object was changed in some way. Flash filled in the frames in between, hence, the term tween. Using ActionScript, you can create much more dynamic and interactive animation.As for what you can animate, a movie clip or sprite is usually a good answer. These objects can contain graphics, and they can have methods and properties that allow them to be moved, scaled, rotated, and otherwise transformed any way you see fit. A movie clip would normally be used only in the Flash authoring environment, where additional frames are added, as in a tween.Finally, you need some way of getting the changes to occur over time. Your best bet is either an enterFrame handler or a timer. ActionScript statements can be used to make changes to the animated object’s properties on each frame, or timer cycle, if you’re using a timer. Since motion is the most obvious kind of animation, the examples in this chapter start out by moving objects around. As the chapter progresses, you’ll see some examples that apply the same techniques to other properties, such as animating the size of an object or its orientation.You have a graphic in a sprite and you want to animate it, giving it some motion.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- Introduction
- InhaltsvorschauAnimation can be defined as any visual change over time. If an image does not change over a period of time, it’s impossible to tell whether it is a still image or an animation. There are a variety of properties you can manipulate to produce change, and thus animation. The most obvious is changing an object’s position to make it move. You can also change its size, shape, rotation, transparency or color, to name a few. As long as something changes visually, the viewer never sees the animation.In the earliest versions of Flash, most animation was done by using tweens. An object was placed on a keyframe, another keyframe was made, and the object was changed in some way. Flash filled in the frames in between, hence, the term tween. Using ActionScript, you can create much more dynamic and interactive animation.As for what you can animate, a movie clip or sprite is usually a good answer. These objects can contain graphics, and they can have methods and properties that allow them to be moved, scaled, rotated, and otherwise transformed any way you see fit. A movie clip would normally be used only in the Flash authoring environment, where additional frames are added, as in a tween.Finally, you need some way of getting the changes to occur over time. Your best bet is either an enterFrame handler or a timer. ActionScript statements can be used to make changes to the animated object’s properties on each frame, or timer cycle, if you’re using a timer. Since motion is the most obvious kind of animation, the examples in this chapter start out by moving objects around. As the chapter progresses, you’ll see some examples that apply the same techniques to other properties, such as animating the size of an object or its orientation.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- Moving an Object
- InhaltsvorschauYou have a graphic in a sprite and you want to animate it, giving it some motion.Decide on a velocity for the x or y-axis (or both), and add that velocity to the object’s position on each frame or animation interval.Velocity is often incorrectly defined as speed. However, velocity also includes a direction factor. For example, “10 miles per hour” is speed, but “10 miles per hour due north” is a velocity. If you are dealing with velocity on the x or y-axis, the direction is inherent. A positive x velocity is to the right; negative to the left. Likewise, a positive y velocity is down, and negative is up.The first example defines the x velocity, _
vx, and sets it to 3. Since this example uses the enterFrame event for animation, the object will move three pixels to the right on each frame:package { import flash.display.Sprite; import flash.events.Event; public class Velocity extends Sprite { private var _sprite:Sprite; private var _vx:Number = 3; public function Velocity( ) { _sprite = new Sprite( ); _sprite.graphics.beginFill(0x0000ff, 100); _sprite.graphics.drawCircle(0, 0, 25); _sprite.graphics.endFill( ); _sprite.x = 50; _sprite.y = 100; addChild(_sprite); addEventListener(Event.ENTER_FRAME, onEnterFrame); } public function onEnterFrame(event:Event):void { _sprite.x += _vx; } } }If you set _vxto -3 instead, you’ll see that it goes in the opposite direction. You can also add in some y velocity by creating a _vyvariable, giving it a value, and changing theonEnterFramemethod, as follows:public function onEnterFrame(event:Event):void { _sprite.x += _vx; _sprite.y += _vy; }If you aren’t a fan of frame-based animation (as in the previous example), you can use a timer function instead, as shown here in bold:Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Moving an Object in a Specific Direction
- InhaltsvorschauYou want to move an object at a certain speed in a specific angular direction.Convert the speed and angle to x and y velocities and add these to the object’s x and y position on each frame or animation interval.Recipe 11.1 explains how you can move something at specific velocities on the x and y-axes, but what if you just know the angle and speed you want an object to move? For example, you want the object to move at an angle of 135 degrees, with a speed of 4 pixels per frame.You can use some basic trigonometric functions to convert this angle and speed to component x and y velocities. First, you need to make sure the angle is in radians. If the angle is in degrees, convert it by using the following formula:
radians = degrees * Math.PI / 180;
If you ever need to convert the opposite way, use:degrees = radians * 180 / Math.PI;
Once you have the angle in radians, use the Math.sin and Math.cos functions, along with the speed, to find the x and y velocities, using the following formulas:vx = Math.cos(angle) * speed; vy = Math.sin(angle) * speed;
Then you can simply move the object as outlined in Recipe 11.1. Here is an example using 135 degrees and a speed of 4 pixels per frame:package { import flash.display.Sprite; import flash.events.Event; import flash.events.TimerEvent; import flash.utils.Timer; public class AngularVelocity extends Sprite { private var _sprite:Sprite; private var _angle:Number = 135; private var _speed:Number = 4; private var _timer:Timer; public function AngularVelocity ( ) { _sprite = new Sprite( ); _sprite.graphics.beginFill(0x0000ff, 100); _sprite.graphics.drawCircle(0, 0, 25); _sprite.graphics.endFill( ); _sprite.x = 200; _sprite.y = 100; addChild(_sprite); _timer = new Timer(30); _timer.addEventListener("timer", onTimer); _timer.start( ); } public function onTimer(event:TimerEvent):void { var radians:Number = _angle * Math.PI / 180; var vx:Number = Math.cos(radians) * _speed; var vy:Number = Math.sin(radians) * _speed; _sprite.x += vx; _sprite.y += vy; } } }Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Easing
- InhaltsvorschauYou want an object to smoothly move to a specific location, slow down, and stop as it reaches that spot.Use an easing formula.First, we’ll look at the concept of simple easing. You have an object at a certain position and you want it to ease to another position. Take the distance between the two points and move the object a fraction of that distance—maybe one-half, one-third, or less. On the next iteration, find the new distance and move the object a fraction of that. Continue this way until the object is so close to the target that you can consider it there.You’ll see that the first couple of jumps are quite big, but successive jumps get smaller and smaller until the object appears not to be moving at all. Viewed in terms of velocity, the velocity starts out high and approaches zero. Another way of looking at it is that velocity is dependent on distance. A large distance makes for a high velocity.The following example shows a simple example of easing. The target position is specified by _
targetXand_targetY. The fraction that the object moves each time is set in_easingSpeed. Here it is set to 0.1, which means the object moves one-tenth of the distance to the target on each animation interval:package { import flash.display.Sprite; import flash.events.Event; import flash.events.TimerEvent; import flash.utils.Timer; public class Easing extends Sprite { private var _sprite:Sprite; private var _easingSpeed:Number = 0.1; private var _targetX:Number = 400; private var _targetY:Number = 200; private var _timer:Timer; public function Easing( ) { _sprite = new Sprite( ); _sprite.graphics.beginFill(0x0000ff, 100); _sprite.graphics.drawCircle(0, 0, 25); _sprite.graphics.endFill( ); _sprite.x = 50; _sprite.y = 50; addChild(_sprite); _timer = new Timer(30); _timer.addEventListener("timer", onTimer); _timer.start( ); } public function onTimer(event:TimerEvent):void { var vx:Number = (_targetX - _sprite.x) * _easingSpeed; var vy:Number = (_targetY - _sprite.y) * _easingSpeed; _sprite.x += vx; _sprite.y += vy; } } }Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Acceleration
- InhaltsvorschauYou want an object to start moving slowly and then speed up over time.Apply acceleration.Many people think of acceleration as simply speeding up. After all, when you want to go faster in your car, you step on the accelerator. A more scientific definition would be a change in velocity. Although this certainly encompasses increasing an object’s speed, it also applies to slowing it down or changing its direction.Acceleration requires an understanding of velocity as covered in Recipes 11.1 and 11.2. Acceleration also has a magnitude and direction, which can be represented as acceleration on the x and y-axes. With each frame or animation interval, the acceleration of each axis is added to the velocity on that axis, and then the velocity is added to the position, as in Recipe 11.1.The following example uses the variables
_axand_ayfor acceleration and_vxand_vyfor velocity:package { import flash.display.Sprite; import flash.events.Event; public class Accel extends Sprite { private var _sprite:Sprite; private var _ax:Number = .3; private var _ay:Number = .2; private var _vx:Number = 0; private var _vy:Number = 0; public function Accel( ) { _sprite = new Sprite( ); _sprite.graphics.beginFill(0x0000ff, 100); _sprite.graphics.drawCircle(0, 0, 25); _sprite.graphics.endFill( ); _sprite.x = 50; _sprite.y = 100; addChild(_sprite); addEventListener(Event.ENTER_FRAME, onEnterFrame); } public function onEnterFrame(event:Event):void { _vx += _ax; _vy += _ay; _sprite.x += _vx; _sprite.y += _vy; } } }As you can see, the sprite starts out motionless and gradually picks up speed as it goes across the stage. Generally, since acceleration is additive, the acceleration values should start out small; velocity builds up quickly over time.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Springs
- InhaltsvorschauYou want an object to jump to and settle at a specific point, as if it were attached by a spring or rubber band.Use Hooke’s Law, the formula for a spring.Hooke’s Law describes the forces at work in a spring. In simple terms, it says that the force applied by the spring (acceleration) is proportional to how far it is stretched. This makes total sense. For example, if you barely pull on a rubber band, it snaps back lightly. But if you pull it back as far as you can, it snaps back with enough force to be painful.Obviously, springs have different amounts of “springiness” or tension. Some are easy to stretch and won’t snap back too strongly. Others require a lot more force to pull, and will spring back with an equally strong force. A number can be used to represent each spring’s strength. The variable _
krepresents this constant, and it is generally a small fraction of 1. A value such as 0.1 or 0.2 works well.When a spring is modeled with ActionScript, you also need to specify a target point that the spring will pull the object to. Finally, you need to apply some damping or friction. In the real world, as an object springs back and forth, it loses a bit of energy and eventually comes to rest somewhere. If you don’t add dampening to your code, the object just springs back and forth forever. To apply damping, multiply the velocity values by a fraction, such as 0.95. This removes 5 percent of its speed on each frame, eventually slowing it down to a stop. Here is an example, with all these principles in place:package { import flash.display.Sprite; import flash.events.Event; public class Spring extends Sprite { private var _sprite:Sprite; private var _vx:Number = 20; private var _vy:Number = 0; private var _k:Number = .1; private var _damp:Number = .94; private var _targetX:Number = 200; private var _targetY:Number = 200; public function Spring( ) { _sprite = new Sprite( ); _sprite.graphics.beginFill(0x0000ff, 100); _sprite.graphics.drawCircle(0, 0, 25); _sprite.graphics.endFill( ); _sprite.x = 0; _sprite.y = 0; addChild(_sprite); addEventListener(Event.ENTER_FRAME, onEnterFrame); } public function onEnterFrame(event:Event):void { var ax:Number = (_targetX - _sprite.x) * _k; var ay:Number = (_targetY - _sprite.y) * _k; _vx += ax; _vy += ay; _sprite.x += _vx; _sprite.y += _vy; _vx *= _damp; _vy *= _damp; } } }Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Using Trigonometry
- InhaltsvorschauYou want to do some advanced animation, involving rotation, circular motion, or oscillation.Use the built-in math functions Math.sin( ), Math.cos( ), and Math.atan2( ).Recipes 11.2 and 11.4 touched on the use of the sine and cosine functions, but they can be used for many other useful effects, such as moving objects in circular or oval paths, smoothly back and forth around a position, or rotating to a particular angle. Both Math.sin( ) and Math.cos( ) are based on the properties of a right triangle (a triangle that has one 90-degree angle). Without getting into a trigonometry lesson, if you feed either function a series of increasing numbers, they will return values that go smoothly back and forth from -1 to 0, 1, 0, and back to -1, continuously. The following code snippet demonstrates this:
for(var i:Number = 0; i < 10; i += 0.1) { trace(Math.sin(i)); }This traces a long list of numbers. If you examine those numbers, you’ll see that they start at 0, go up to 0.999, back down to -0.999, back up, and so on. You can now multiply that by another number, say 40, and get a list of values from -40 to 40. If you use this in an enterFrame handler, or timer-based method, and apply the result to an object’s position, you can get it to oscillate back and forth, or up and down, as the following example shows:package { import flash.display.Sprite; import flash.events.Event; public class Oscillation extends Sprite { private var _sprite:Sprite; private var _angle:Number = 0; private var _radius:Number = 100; public function AS3CB( ) { _sprite = new Sprite( ); _sprite.graphics.beginFill(0x0000ff, 100); _sprite.graphics.drawCircle(0, 0, 25); _sprite.graphics.endFill( ); _sprite.x = 0; _sprite.y = 100; addChild(_sprite); addEventListener(Event.ENTER_FRAME, onEnterFrame); } public function onEnterFrame(event:Event):void { _sprite.x = 200 + Math.sin(_angle) * _radius; _angle += .05; } } }Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Applying Animation Techniques to Other Properties
- InhaltsvorschauYou want to apply the techniques in this chapter’s recipes to something other than an object’s motion.Apply the techniques as given, but assign the results to a property other than the object’s x and y position.Although changing an object’s position is the most obvious method of animation, all of the techniques in this chapter can be applied to almost any property of a movie clip or sprite. This recipe provides several examples to get you started, but the possibilities are so numerous that it would be impossible to list them all.First, try applying some velocity to the rotation property; this variable is called
_vrfor rotational velocity:package { import flash.display.Sprite; import flash.events.Event; public class AnimatingRotation extends Sprite { private var _sprite:Sprite; private var _vr:Number = 4; public function AS3CB( ) { _sprite = new Sprite( ); _sprite.graphics.beginFill(0xffffff, 100); _sprite.graphics.drawRect(-50, -20, 100, 40); _sprite.graphics.endFill( ); _sprite.x = 100; _sprite.y = 100; addChild(_sprite); addEventListener(Event.ENTER_FRAME, onEnterFrame); } public function onEnterFrame(event:Event):void { _sprite.rotation += _vr; } } }This example uses a rectangle instead of a circle, so you can see the rotation in action. It sets _vrto 4, and then adds that to the sprite’s rotation on each frame.The next example applies a spring formula to the scale of the sprite. A click handler sets a random target scale, and the enterFrame handler applies the spring action. When you click on the sprite, it bounces to a new size:package { import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; public class AnimatingProperties extends Sprite { private var _sprite:Sprite; private var _k:Number = 0.1; private var _damp:Number = 0.9; private var _scaleVel:Number = 0; private var _targetScale:Number = 1; public function AS3CB( ) { _sprite = new Sprite( ); _sprite.graphics.beginFill(0xffffff, 100); _sprite.graphics.drawRect(-50, -50, 100, 100); _sprite.graphics.endFill( ); _sprite.x = 100; _sprite.y = 100; addChild(_sprite); addEventListener(Event.ENTER_FRAME, onEnterFrame); _sprite.addEventListener(MouseEvent.CLICK, onClick) } public function onEnterFrame(event:Event):void { _scaleVel += (_targetScale - _sprite.scaleX) * _k _sprite.scaleX += _scaleVel; _sprite.scaleY = _sprite.scaleX; _scaleVel *= _damp; } public function onClick(event:MouseEvent):void { _targetScale = Math.random( ) * 2 - .5; } } }Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Chapter 12: Strings
- InhaltsvorschauStrings are the fundamental textual element of the ActionScript language. A string is a series of zero or more characters enclosed in single or double quotes. Unlike some other languages, ActionScript does not differentiate between single characters and strings. Both characters and strings are grouped into the String datatype. For example:
var exampleA:String = "this is a string"; var exampleB:String = 'this is also a string'; var exampleC:String = "strings can contain characters such as –(*+5~"; var exampleD:String = ""; // Empty string var exampleE:String = "x"; // Single character var exampleF:String; // Defaults to null when no value is assigned
String values must always be enclosed within quotes. You can use either single or double quotes, but the starting and ending quotes enclosing a string must be of the same type.// Both of these strings cause errors because of mismatched quotes. var exampleA:String = "an incorrect string'; // Ending quote should be double var exampleB:String = 'another incorrect string"; // Ending quote should be single
ActionScript provides functionality that allows you to work with strings and characters in many ways. A new feature of ActionScript 3.0 relating to strings is the built-in support for regular expressions (pattern matching), which is covered in Chapter 13.You want to concatenate (join) together two or more strings into a single value.Use the string concatenation operator+, the combination concatenation-assignment operator+=, or the String.concat( ) method.Multiple strings can be joined in a single expression using the concatenation operator,+, between two string operands:// This results in a single value of "Thisworks" (no space) var example:String = "This" + "works";
If you want to join more than two strings, use additional concatenation operators and string value operands in the appropriate order:Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Introduction
- InhaltsvorschauStrings are the fundamental textual element of the ActionScript language. A string is a series of zero or more characters enclosed in single or double quotes. Unlike some other languages, ActionScript does not differentiate between single characters and strings. Both characters and strings are grouped into the String datatype. For example:
var exampleA:String = "this is a string"; var exampleB:String = 'this is also a string'; var exampleC:String = "strings can contain characters such as –(*+5~"; var exampleD:String = ""; // Empty string var exampleE:String = "x"; // Single character var exampleF:String; // Defaults to null when no value is assigned
String values must always be enclosed within quotes. You can use either single or double quotes, but the starting and ending quotes enclosing a string must be of the same type.// Both of these strings cause errors because of mismatched quotes. var exampleA:String = "an incorrect string'; // Ending quote should be double var exampleB:String = 'another incorrect string"; // Ending quote should be single
ActionScript provides functionality that allows you to work with strings and characters in many ways. A new feature of ActionScript 3.0 relating to strings is the built-in support for regular expressions (pattern matching), which is covered in Chapter 13.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Joining Strings
- InhaltsvorschauYou want to concatenate (join) together two or more strings into a single value.Use the string concatenation operator
+, the combination concatenation-assignment operator+=, or the String.concat( ) method.Multiple strings can be joined in a single expression using the concatenation operator,+, between two string operands:// This results in a single value of "Thisworks" (no space) var example:String = "This" + "works";
If you want to join more than two strings, use additional concatenation operators and string value operands in the appropriate order:// Results in a single value of "This works" (with a space) var example:String = "This" + " " + "works";
In the preceding examples, there is little reason why you would need to join the string literals instead of assigning a single string value ("This works"instead of"This" + " " + "works"). However, this demonstrates the technique you’ll use when working with dynamic values. You can use the concatenation operator to join not only string literals, but also variables containing string values (or values that can be converted to strings). For example:var attendance:int = 24; // Results in a single value of "There are 24 people" var output:String = "There are " + attendance + " people";
The concatenation operator automatically converts any nonstring values to strings, as long as at least one of the operands in the statement is a string. In the preceding example, the numerical value 24 is converted to the string value 24 automatically before being joined with the other strings. However, if all the operands are numbers, the ActionScript interpreter treats the+operator as the addition operator instead of the concatenation operator:var first:int = 24; var second:int = 42; // Results in the compiler error, "Implicit coercion of a value // type 'Number' to an unrelated type 'String'" var result:String = first + second;
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Using Quotes and Apostrophes in Strings
- InhaltsvorschauYou want to use quotes or apostrophes within a string value.Use a backslash to escape the quotes or apostrophes contained within the string. Alternatively, use single quotes within double quotes, or vice versa.The ActionScript compiler tries to match u p quotes of the same kind (single quotes with single quotes and double quotes with double quotes) when processing string literals. Therefore, if you enclose a string literal within quotes of one type and also try to include the same kinds of quotes in the string value, the code fails to compile as you intended.This string assignment causes an error because of mismatched quotes. In the following example, the string starts with a double quote (
"Yes), therefore, the double quote character before theYsignals the end of the string to the compiler. As such, it does not understand what to do with the remaining characters:var error:String = "He said, "Yes.""; // Incorrect.
One possible solution is to use single quotes to enclose a string literal that contains double quotes, or double quotes to enclose a string literal that contains single quotes, as follows:// This assignment works. The result is a string: He said, "Yes." var exampleA:String = 'He said, "Yes."'; // This assignment also works. The result is a string: He said, 'Yes.' var exampleB:String = "He said, 'Yes.'";
However, if the string value contains both single and double quotes, this technique does not work. Furthermore, you have to pay close attention to what type of quotes are used when creating the strings, and you lose consistency in your program with constant quote switching. An alternative solution, which works all the time, is to use the backslash character (\\) to escape any quotes used within the string value (i.e., escape the quote by preceding it by a backslash):Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Inserting Special Whitespace Characters
- InhaltsvorschauYou want to add whitespace characters, such as tabs or newline characters, to your string.Use the escape sequences for the special characters.There are five special whitespace characters with escape sequences, as shown in Table 12-1.
Table : Whitespace escape sequences Whitespace character Escape sequence Newline \\nTab \\t
Backspace \\b
Form feed \\fCarriage return \\rYou can use these escape sequences within a string; they are most useful when displaying a string value in a text field:// Results in a string value: these words are separated by tabs var example:String = "these\\twords\\tare\\tseparated\\tby\\ttabs"; /* Results in a string value: these words are separated by newlines */ var example:String = "these\\nwords\\nare\\nseparated\\nby\\nnewlines";
Unlike previous versions of ActionScript, ActionScript 3.0 no longer includes support for thenewlineconstant. If you have code that usesnewlineanywhere, you will need to replace it with the\\nescape sequence.The result is the same.// Generates a compile error – replace newline with "\\n" to compile var error:String = "two" + newline + "lines"; // Compile error: "Access of // undefined property 'newline'"Within Flash, the newline, form feed, and carriage return characters all result in the same display. However, when you load content into Flash from external sources, some values will have newline characters, some will have form feeds, and some will have carriage returns.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Searching for a Substring
- InhaltsvorschauYou want to find a string value inside of a string.Use the indexOf( ) or lastIndexOf( ) methods from the String class.You can use the indexOf( ) and lastIndexOf( ) methods to determine whether a string contains a specified substring value. Each method returns the starting index of the substring found. The indexOf( ) method searches from left to right, whereas the lastIndexOf( ) methods searches from right to left in the string. If the substring is not found, the value -1 is returned.The indexOf( ) method takes two parameters:
- substring
-
The substring value for which you want to search.
- startIndex
-
The optional zero-based starting position from which to search within the string. Zero-based means the first character in the string is at position 0, not 1. If omitted, the method begins the search from the beginning of the string (at index 0).
If you want to test whether a string contains another string, you can use the indexOf( ) method with only one parameter. For example:var example:String = "This string contains the word cool twice. Very cool."; // Get the index of the first occurrence of the substring "cool" within example. var index:int = example.indexOf( "cool" ); // If the indexOf( ) method returns –1, no occurrences of "cool" were found. if ( index != -1 ) { // Displays: "String contains word cool at index 30" because the first // occurrence of the substring appears starting at index 30 within example. trace( "String contains word cool at index " + index ); }
You can get the indices of subsequent occurrences of a substring by specifying the second, optional parameter of theEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Extracting a Substring
- InhaltsvorschauYou want to extract a substring from a string.Use the substring( ), substr( ), or slice( ) methods.The substring( ), substr( ), and slice( ) methods all return the value of a substring without affecting the original string. The only difference between the three methods is in the parameters they accept.The substr( ) method takes up to two parameters.
- startIndex
-
The position of the first character of the substring. The value can be negative, in which case the index is calculated from the end of the string, where -1 is the last character, -2 is the second-to-last character, and so on.
- length
-
The number of characters in the substring to extract. If this parameter is omitted, all the characters from the start index to the end are used.
var example:String = "Bunnies"; trace( example.substr( 0 ) ); // Displays: Bunnies trace( example.substr( 0, 3 ) ); // Displays: Bun trace( example.substr( 3, 3 ) ); // Displays: nie trace( example.substr( -1 ) ); // Displays: s trace( example.substr( -2, 5 ) ); // Displays: es
The substring( ) and slice( ) method both take the same parameters.startIndex-
The position of the first character of the substring to extract.
endIndex-
The position of one character after the last character in the substring to extract. That is, the substring will include from start index up to, but not including, the character at
endIndex. If this parameter is omitted, all the characters from the start index to the end of the string are used.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Parsing a String into Words
- InhaltsvorschauYou want to process the individual words in a string.Use the split( ) method.The split( ) method, Recipe 5.6, splits a string into an array using the specified delimiter. To split a string into words, use the split( ) method with a space as the delimiter.
// Create a string with multiple words. var example:String = "This is a string of words"; // Split the string into an array of words using a space as the delimiter. var words:Array = example.split( " " ); // Loop through the array and do something with each word. // In this example, just output the values. for ( var i:int = 0; i < words.length; i++ ) { /* Displays: this is a string of words */ trace( words[i] ); }You can process the individual words in many ways. The following is a complete example that uses this technique to split a string into words and then creates sprites containing those words. The user can then drag the words around on stage to form various sentences or statements similar to the popular magnetic poetry kits:package { import flash.display.Sprite; import flash.events.MouseEvent; import flash.text.TextField; import flash.text.TextFieldAutoSize; import flash.display.StageAlign; import flash.display.StageScaleMode; public class ActionScriptPoetry extends Sprite { public function ActionScriptPoetry( ) { stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; // Create a string, and split the string into an array of words. var example:String = "This is a string of ActionScript poetry words"; var words:Array = example.split(" "); var word:Sprite; var wordText:TextField; // Loop through all the words in the array. for ( var i:int = 0; i < words.length; i++ ) { // Create a new sprite for each word and add it to the // display list so the sprite is drawn on-screen word = new Sprite( ); addChild( word ); // Create a text field within the sprite by creating a new // TextField instance and adding it as a child wordText = new TextField( ); word.addChild( wordText ); // The text field should autosize to fit its contents. It should also have // a border and background so that it mimics the look of poetry magnets, // and the text should not be selectable since we want to drag it around. wordText.autoSize = TextFieldAutoSize.LEFT; // Left-justify the text wordText.border = true; wordText.background = true; wordText.selectable = false; // Set each text fields's text value to one of the words from the array. wordText.text = words[i]; // The sprite is draggable when clicked, and it stops being // draggable when released. word.addEventListener( MouseEvent.MOUSE_DOWN, handleDrag ); word.addEventListener( MouseEvent.MOUSE_UP, handleDrop ); // Randomize the position of the sprites containing words var rx:Number = Math.random( ) * stage.stageWidth - word.width; var ry:Number = Math.random( ) * stage.stageHeight - word.height; word.x = rx; word.y = ry; trace(word); } } // This function is called when the uses presses a word with the mouse private function handleDrag( event:MouseEvent ):void { // The event target will be the TextField, so to get the // word we work up to the parent var word:Sprite = event.target.parent; // Make the clicked on word draw on top of everything else setChildIndex( word, numChildren - 1 ); // Drag the word around to coincide with mouse movement word.startDrag( ); } // This function is called when the user releases the mouse private function handleDrop( event:MouseEvent ):void { // The event target will be the TextField, the parent is the Sprite var word:Sprite = event.target.parent; // Stop moving the word around with the mouse word.stopDrag( ); } } }Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Removing and Replacing Characters and Words
- InhaltsvorschauYou want to remove characters from a string or replace one substring with another.Use the replace( ) method or split( ) and join( ) combination.ActionScript 3.0 includes a new method String.replace( ), not found in previous versions, that allows you to replace substrings within a string. This method accepts two parameters:
pattern-
The substring or regular expression you want to find and replace.
replace-
The value with which to replace each
patternmatch. This value is typically a string but can also be a function that returns a string. It is useful whenpatternis a regular expression.
There are two uses of this method based on the parameters provided. This recipe focuses on using a string for the pattern. A regular expression pattern also can be used, as covered in Recipe 13.4.Here is a simple example of replacing a substring in a sentence. The replace( ) method returns a new string withpatternreplaced byreplace, leaving the original string unmodified.var example:String = "This is a cool sentence." // Replace " is " with " is not " in example. // Displays: This is not a cool sentence. trace( example.replace( " is ", " is not " ) );
In this example, the word “is” is surrounded by spaces when used as the pattern. This is important because failing to do so matches the “is” in “This” and the sentence starts with “This not is,” which is not the desired effect.When a string is used for thepatternin the replace( ) method, the method lacks functionality compared to using a regular expression. The two biggest problems are that only the first occurrence of pattern is replaced and you have to roll your own solution for case-insensitive replacement.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Retrieving One Character at a Time
- InhaltsvorschauYou want to retrieve one character at a time from a string.Use a for statement and the String.charAt( ) method. Alternatively, use String.split( ) with the empty string as the delimiter to split the string into an array of all the characters, and then use a for statement to loop through the array.The simplest way to extract each character of a string is to use a for statement that loops over all of the character positions in the string from index zero to
string.length – 1, incrementing by one on each iteration. Within the for statement body, you can use the charAt( ) method to extract the character for processing.var example:String = "a string"; // Loop over all of the chatacters of the string. for ( var i:int = 0; i < example.length; i++ ) { /* Output each character, one at a time. This displays: a s t r i n g */ trace( example.charAt( i ) ); }You can achieve the same effect by using the split( ) method to first split the string into an array of characters, and then looping through the array to process each character. Use the empty string as the delimiter parameter for the split( ) method to break between each character.var example:String = "a string"; // Split the string into an array of characters (one-character strings). var characters:Array = example.split( "" ); // Loop through all the elements of the characters array. for ( var i:int = 0; i < characters.length; i++ ) { /* Output each character element. This displays: a s t r i n g */ trace( characters[i] ); }Both techniques are generally interchangeable, though the second one offers some advantages if you want to work with the characters by using common array methods. For example, if you first split a string into an array of characters, you can sort that array. This is not as easily done when you use theEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Converting Case
- InhaltsvorschauYou want to change the case of a string or perform a case-insensitive comparison.Use the to UpperCase( ) and toLowerCase( ) methods.The toUpperCase( ) and toLowerCase( ) methods return new strings in which all the characters are uppercase or lowercase, respectively, without modifying the original string. This is useful in situations in which you want to ensure uniformity of case. For example, you can use toLowerCase( ) or toUpperCase( ) to perform case-insensitive searches within strings, as is shown in Recipe 12.4. Both methods affect alphabetical characters only, leaving non-alphabetic characters unchanged:
var example:String = "What case?"; // Displays: what case? trace( example.toLowerCase( ) ); // Displays: WHAT CASE? trace( example.toUpperCase( ) ); // The original string value is unchanged: What case? trace( example );
Both methods return a new string. To alter the original string, reassign the return value to it, as follows:var example:String = example.toLowerCase( );
You can use toLowerCase( ) and toUpperCase( ) in concert to capitalize the first letter of a word. The custom ascb.util.StringUtilities.toInitialCap( ) method does just that. The following is the code in the StringUtilities class in which the toInitialCap( ) method is defined:public static function toInitialCap( original:String ):String { return original.charAt( 0 ).toUpperCase( ) + original.substr( 1 ).toLowerCase( ); }The following is an example usage of the method:var example:String = "bRuCE"; trace( StringUtilities.toInitialCap( example ) ); // Displays: Bruce
The toTitleCase( ) method converts a string to so-called title case (initial letters capitalized). The following is the definition of the method:public static function toTitleCase( original:String ):String { var words:Array = original.split( " " ); for (var i:int = 0; i < words.length; i++) { words[i] = toInitialCap( words[i] ); } return ( words.join( " " ) ); }Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Trimming Whitespace
- InhaltsvorschauYou want to trim the whitespace from the beginning and end of a string.Use the custom ascb.util.StringUtilities.trim( ) method. Alternatively, if you are using the Flex 2 framework, you can use the mx.utils.StringUtil.trim( ) static method.Extra whitespace at the beginning and end of a string is a common enough annoyance that you should have a way of dealing with it. ActionScript does not provide a native trim( ) implementation, so you have to either write your own or use a pre-coded solution.The basic steps involved are as follows.
-
Split the string into an array of characters.
-
Remove whitespace elements at the beginning of the array until there is not a whitespace character (tab, form feed, carriage return, newline, or space).
-
Remove whitespace elements at the end of the array.
-
Use join( ) to form the array characters into a single string and return that value.
The ascb.util.StringUtilities.trim( ) method works as described in the preceding steps. The following is the actual definition of the method, along with the isWhitespace( ) helper method:// Returns true if the character is a whitespace character public static function isWhitespace( ch:String ):Boolean { return ch == '\\r' || ch == '\\n' || ch == '\\f' || ch == '\\t' || ch == ' '; } public static function trim( original:String ):String { // Split the string into an array of characters. var characters:Array = original.split( "" ); // Remove any whitespace elements from the beginning of the array using // splice( ). Use a break statement to exit the loop when you reach a // non-whitespace character to prevent it from removing whitespace // in the middle of the string. for ( var i:int = 0; i < characters.length; i++ ) { if ( isWhitespace( characters[i] ) ) { characters.splice( i, 1 ); i--; } else { break; } } // Loop backward through the array removing whitespace elements until a // non-whitespace character is encountered. Then break out of the loop. for ( i = characters.length - 1; i >= 0; i-- ) { if ( isWhitespace( characters[i] ) ) { characters.splice( i, 1 ); } else { break; } } // Recreate the string with the join( ) method and return the result. return characters.join(""); }Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Reversing a String by Word or by Character
- InhaltsvorschauYou want to reverse a string either by word or by character.Use the split( ) method to create an array of the words/characters and use th e reverse( ) and join( ) methods on that array.You can reverse a string by word or character by using the same process. The only difference is in the delimiter you use in the split( ) method and the joiner you use in the join( ) method. In either case, the basic algorithm is:
-
Split the string into an array, using a space as the delimiter for words or the empty string as the delimiter for characters.
-
Call the reverse( ) method of the array, which reverses the order of the elements.
-
Use the join( ) method to reconstruct the string. When you are reversing by word, use a space as the joiner; when reversing by character, use the empty string as the joiner:
The following code illustrates the process:var example:String = "hello dear reader"; // Split the string into an array of words. var words:Array = example.split( " " ); // Reverse the array. words.reverse( ); // Join the elements of the array into a string using spaces. var exampleRevByWord:String = words.join( " " ); // Displays: reader dear hello trace( exampleRevByWord ); // Split the string into an array of characters. var characters:Array = example.split( "" ); // Reverse the array elements. characters.reverse( ); // Join the array elements into a string using the empty string. var exampleRevByChar:String = characters.join( "" ); // Displays: redaer raed olleh trace( exampleRevByChar );
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Converting Between Strings and Unicode or ASCII
- InhaltsvorschauYou want to convert between characters and their corresponding Unicode code point (a.k.a. character code). Or you want to convert strings to and from ASCII codes.Use the String.charCodeAt( ) and String.fromCharCode( ) methods.You can use fromCharCode( ) to display characters you cannot directly enter into your Flash document. The method is a static method, which means that it is invoked from the top-level String object instead of from a string instance. It takes an integer or a series of integers and coverts the character codes to their string equivalents. When values less than 128 are used, fromCharCode( ) essentially converts a numeric ASCII code to its equivalent character:
/* Displays: New paragraph: ¶ Cents: ¢ Name: Darron */ trace( "New paragraph: " + String.fromCharCode( 182 ) ); trace( "Cents: " + String.fromCharCode( 162 ) ); trace( "Name: " + String.fromCharCode( 68, 97, 114, 114, 111, 110 ) );
The charCodeAt( ) method can be used to retrieve the code point of the character at a particular index of a string. For characters whose Unicode code point is less than 128, charCodeAt( ) converts a character to its equivalent ASCII code:var example:String = "abcd"; // Outputs the code point, 97, of the first character, a. trace( example.charCodeAt( 0 ) );
The fromCharCode( ) method is an alternative to using Unicode escape sequences to display special characters. However, you can also use fromCharCode( ) in concert with charCodeAt( ) to test for the existence of special characters:var example:String = String.fromCharCode( 191 ) + "D" + String.fromCharCode( 243 ) + "nde est" + String.fromCharCode( 225 ) + " el ba" + String.fromCharCode( 241 ) + "o?"; // Test whether the first character of the string has the code point of // 191. Use the unicode escape sequence instead of fromCharCode( 191 ) to // produce the speical character. If so displays: The string "¿Dónde está // el baño?" has a ¿ at the beginning. if ( example.charCodeAt( 0 ) == 191 ) { trace( "The string \\"" + example + "\\" has a \\u00BF at the beginning." ); }Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Chapter 13: Regular Expressions
- InhaltsvorschauOne of the most powerful features added to ActionScript 3.0 is regular expressions (more commonly known as regexes or regexps). Regular expressions are, put simply, patterns that can be matched against strings. You may be familiar with other types of patterns, such as wildcards (e.g.,
*and?), which can be used to match patterns while searching for files. Patterns are also used in Recipe 9.5. Regular expressions support this type of pattern matching, but they are also much more sophisticated.Regular expressions can be useful in many situations. For instance, the patterns can be applied against strings to perform a variety of tasks, including:-
Finding substrings beginning with a vowel (a, e, i, o, or u)
-
Extracting specific values within a string, such as the year value from a full date
-
Validating user input to ensure an email address is formatted correctly
-
Stripping out HTML tags from a block of text to remove the markup
The patterns used for regular expressions are built by combining characters that have special meaning and can range from being very simple:[a-zA-Z]
to being extremely complex and cryptic, such as this regex for matching a valid IP address:^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$
Simple patterns, such as.*, are easy to understand, but more complex patterns are difficult to learn and are even harder to implement. Thankfully, every regular expression can be broken down into a plain English description. For example, the simple regular expression.*means “any character repeated any number of times.” More complex patterns, such as(A|a)ction(S|s)cript, are no different because they are built by combining simple patterns in various ways. The patternEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Introduction
- InhaltsvorschauOne of the most powerful features added to ActionScript 3.0 is regular expressions (more commonly known as regexes or regexps). Regular expressions are, put simply, patterns that can be matched against strings. You may be familiar with other types of patterns, such as wildcards (e.g.,
*and?), which can be used to match patterns while searching for files. Patterns are also used in Recipe 9.5. Regular expressions support this type of pattern matching, but they are also much more sophisticated.Regular expressions can be useful in many situations. For instance, the patterns can be applied against strings to perform a variety of tasks, including:-
Finding substrings beginning with a vowel (a, e, i, o, or u)
-
Extracting specific values within a string, such as the year value from a full date
-
Validating user input to ensure an email address is formatted correctly
-
Stripping out HTML tags from a block of text to remove the markup
The patterns used for regular expressions are built by combining characters that have special meaning and can range from being very simple:[a-zA-Z]
to being extremely complex and cryptic, such as this regex for matching a valid IP address:^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$
Simple patterns, such as.*, are easy to understand, but more complex patterns are difficult to learn and are even harder to implement. Thankfully, every regular expression can be broken down into a plain English description. For example, the simple regular expression.*means “any character repeated any number of times.” More complex patterns, such as(A|a)ction(S|s)cript, are no different because they are built by combining simple patterns in various ways. The patternEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Understanding Regular Expression Patterns
- InhaltsvorschauYou want to understand the basic building blocks of regular expressions.Regular expressions are built by combining characters with special meaning. First start by learning the basic patterns, and then use this knowledge to put together more complex patterns.A regular expression is a pattern constructed using the regular expression syntax and is typically used during text processing and pattern matching. The syntax consists of characters, metacharacters, and metasequences. Characters are interpreted literally, whereas metacharacters and metasequences have special meaning in the regular expression context. For example, the regular expression built from the characters
hellomatches the string “hello,” whereas the regular expression consisting only of the.metacharacter means “any character” and matches “a”, “b”, “1”, etc. Additionally, the regular expression built from using the\\dmetasequence matches any digit, such as “1” or “9”.Before getting too in-depth with the regular expression syntax, let’s start by discussing how regular expressions are created in ActionScript 3.0. Regular expressions are built with the RegExp class and can be constructed from either a string describing the pattern or from a regular expression literal. A regular expression literal is a forward slash, followed by the regular expression pattern, followed by another forward slash, such as/pattern/. The following code demonstrates how to create a regular expression for the patternhelloby using both a string and the RegExp constructor, as well as a regular expression literal:// Create a pattern for hello using the RegExp class constructor // passing in a string describing the pattern var example1:RegExp = new RegExp( "hello" ); // Create the same hello pattern using a regular expression literal var example2:RegExp = /hello/;
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Testing Regular Expressions
- InhaltsvorschauYou want to test a regex against a string to determine if a match can be made.Use the RegExp.test( ) and RexExp.exec( ) methods.Recipe 13.1 discusses the building blocks of regular expressions. Once you have created a regular expression that describes the pattern of what you want to find in a string, there are two methods from the RegExp class that can perform the search, test( ) and exec( ).To determine whether a pattern can be matched against a string, use the test( ) method on a RegExp instance. The test( ) method takes the string being tested against as the parameter and returns a Boolean value of
trueif the pattern can be matched, andfalseotherwise:// Create a pattern to match against a string var example:RegExp = /abc/; // Displays: true trace( example.test( "A string with abc in it" ) ); // Displays: true trace( example.test( "abc" ) ); // Displays: false trace( example.test( "Another string to test against..." ) );
The test( ) method returnstrueif the regular expression can be matched anywhere in the string, but it won’t allow you to extract the match or determine where in the string the match was found. To retrieve this information, use the exec( ) method.The exec( ) method works in much the same way that test( ) does, except that instead of returning a Boolean value, an array is returned containing the substring that matched the pattern. If no match is found, exec( ) returnsnull.// Create a pattern to match against a string var example:RegExp = /abc/; // Save the result of a string with a substring that matches // the pattern var result:Array = example.exec( "A string with abc in it" ); // Displays: abc trace( result ); // Displays: 14 trace( result.index ); // Save the result of a string that doesn't contain a match for // the pattern result = example.exec( "A string with no match" ); // Displays null trace( result );
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Looking for Pattern Matches
- InhaltsvorschauYou want to search a string with a regex to find matches to the pattern.Use the String.search( ) and String.match( ) methods.The String.search( ) and RegExp.test( ) methods behave similarly, as discussed in Recipe 13.2. The search( ) method works on a string object and takes a regular expression as a parameter. If the regex can be matched in the string, the starting position for the matching substring is returned. If the regex cannot be matched, -1 is returned:
var example:String = "ActionScript 3 Cookbook"; // Displays: 6 trace( example.search( /script/i ) ); // Displays: -1 trace( example.search( /script/ ) );
In the preceding code block, the search( ) method is first invoked by using a regex that matches the substringscriptin a case-insensitive manner. The matching substringScriptis found at position 6. In the second call to search( ), the same regex is used, but this time without theignoreCaseflag being set. Because the verbatim substringscriptdoes not appear in the example string, -1 is returned.The search( ) method does not respect theglobalflag orlastIndexproperty of the regex passed to it. It always begins its search from the beginning of the string.// Create a global regular expression that matches three-letter words var regex:RegExp = /\\b[a-z]{3}\\b/g; var sentence:String = "This string has two three letter words."; /* Displays: 12 0 12 */ trace( sentence.search( regex ) ); trace( regex.lastIndex ); trace( sentence.search( regex ) );When looking for a match with search( ), it is only ever possible to find the position of the first match, even if the regex is flagged asglobal. ThelastIndexproperty is not automatically adjusted like it is with RegExp.exec( ) (see Recipe 13.2). Additionally, even if you set theEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Removing and Replacing Characters and Words Using Patterns
- InhaltsvorschauYou want to remove characters from a string that matches a regex, or you want to replace pattern matches with a different substring.Use the String.replace( ) method.The String.replace( ) method (see Recipe 12.7) allows you to use a string pattern to replace characters and words. Instead of using a string to define the pattern to replace, a more powerful approach is to use a regular expression.You’ll recall from Recipe 12.7 that the replace( ) method takes two parameters:
pattern-
The substring or regular expression you want to find and replace.
replace-
The value with which to replace each pattern match. This value is typically a string, but can also be a function that returns a string; this is particularly useful when pattern is a regular expression.
Using the replace( ) method is the same as what you’re already familiar with, except instead of using a string pattern, you use a regex. Remember that replace( ) does not modify the original string, so make sure you use the string returned by replace( ) to work with the result:var example:String = "<p>A string with <b>HTML</b> in it</p>"; // Replace the HTML by using a non-greedy global regex, using the empty // string as the replacement substring for every match to the pattern. example = example.replace( /<.*?>/g, "" ); // Displays: A string with HTML in it trace( example );
The preceding code demonstrates how to remove HTML tags within a string. The use of a nongreedy regex is required, as discussed in Recipe 13.5. By using the empty string as the replacement string for all pattern matches, the result is the pattern matches being removed from the original string.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Creating a Nongreedy Pattern
- InhaltsvorschauYou’re using a regular expression but not seeing the correct results. The pattern is acting greedy, matching more characters than you want it to.Replace the regex with a nongreedy version to match the smallest amount of characters possible.Whenever you create a pattern that includes matches for character repetition using the
*and+metacharacters or the{n,m}metasequence, the pattern is greedy. A greedy pattern is one that tries to consume as much text as possible, matching the largest substring it can. Patterns are greedy because of the underlying code in the regular expression engine, and understanding how that engine works allows you to create more precise regexes.Consider that you want to remove HTML tags in a string, as described in Recipe 13.4. Every HTML tag starts with an opening<and ends in a closing>. In between the angle brackets, there could be a wide variety of characters, such a numbers, letters, quotes, the equal sign, etc. For the sake of simplicity, instead of creating a character class for everything that could appear between the<and>, a.*will match “any character, any number of times.” So, you construct the regular expression/<.*>/gand try running it against a string that contains HTML tags:var example:String = "<b>hello</b>, world!"; // Displays: <b>hello</b> trace( example.match( /<.*>/g ) );
You might have expected that the regular expression would produce two matches, one for<b>and another for</b>. From the preceding code block, you can see that only one match was produced, the entire string<b>hello</b>. This is an example of a greedy pattern in action.The first character in the expression is a<, which is taken literally. It matches in the string at the very first position so the engine moves on in the pattern and keeps processing. The next character in the pattern is aEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Validating User Input with Common Patterns
- InhaltsvorschauYou want to make sure that a user correctly entered information, such as an email address, social security number, telephone number, or Zip/Postal Code.Use one of the common patterns included in this recipe.Regular expressions are extremely useful for validating a wide range user input. For example, you might have a form that allows a user to enter an email address to sign up for your latest online game and you need to ensure the email address is valid. Or, you might possibly want to make sure that a birth date was entered correctly. Or, you might want to verify that a credit card number was input properly. The following list of regular expressions will help:
-
Match a date in the format ##/##/####, where both the day and month value can be 1 or 2 digits, and the year can be either 2 digits or 4 digits when starting with 19 or 20:
-
^\\d{1,2}\\/\\d{1,2}\\/(\\d{2}|(19|20)\\d{2})$ -
Match a social security number in the format ###-##-####, where the dashes are optional and the three groups can have optional spacing between them:
-
^\\d{3}\\s*-?\\s*\\d{2}\\s*-?\\s*\\d{4}$ -
Match a five-digit U.S. Zip Code with an optional dash and four-digit extension:
-
^\\d{5}(-\\d{4})?$ -
Match a Canadian Postal Code in the format L#L #L# (where L is a letter). There is a restriction placed on the first letter in the Postal Code to ensure that a valid province, territory, or region is specified:
-
^[ABCEGHJKLMNPRSTVXY]\\d[A-Z] \\d[A-Z]\\d$
-
Match a U.S. telephone number in the format (###) ###-####, where the area code is optional, the parentheses around the area code are optional and could be replaced with a dash, and there is optional spacing between the number groups:
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Chapter 14: Dates and Times
- InhaltsvorschauDates and times are important to many ActionScript applications, particularly when more robust applications are developed to offer services to users. For example, date and time values are important for determining the amount of time that has elapsed for timed operations, for determining whether a user’s trial membership is active or about to expire, and for storing transaction dates.ActionScript stores dates and times internally as epoch milliseconds, the number of milliseconds that have elapsed since the Epoch—midnight, January 1, 1970 Coordinated Universal Time (UTC). For our purposes, UTC is essentially equivalent to the more familiar Greenwich Mean Time (GMT). See the U.S. Naval Observatory’s site (http://aa.usno.navy.mil/faq/docs/UT.html) regarding the subtle distinctions. Many programming languages store dates in terms of the epoch (often in seconds instead of milliseconds); therefore, you can readily work with date and time values that have been imported from other sources (and vice versa).In addition, the Date class allows you to set and get date and time values in terms of years, months, days, and so on by using properties such as
fullYear,month, etc. These properties are for your convenience, but the values are stored internally as epoch milliseconds.You want to know the current date and time.Create a new date by using the Date( ) constructor with no parameters. Alternatively, use a CGI script or any other server-side program to return the server time and create a new Date object from that value.The date and time that ActionScript calculates on its own is based on the client computer’s date and time settings. Therefore, if the user’s computer has the incorrect time, so will the Date object. With that caveat in mind, you can retrieve the current client-side date and time by creating a newEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Introduction
- InhaltsvorschauDates and times are important to many ActionScript applications, particularly when more robust applications are developed to offer services to users. For example, date and time values are important for determining the amount of time that has elapsed for timed operations, for determining whether a user’s trial membership is active or about to expire, and for storing transaction dates.ActionScript stores dates and times internally as epoch milliseconds, the number of milliseconds that have elapsed since the Epoch—midnight, January 1, 1970 Coordinated Universal Time (UTC). For our purposes, UTC is essentially equivalent to the more familiar Greenwich Mean Time (GMT). See the U.S. Naval Observatory’s site (http://aa.usno.navy.mil/faq/docs/UT.html) regarding the subtle distinctions. Many programming languages store dates in terms of the epoch (often in seconds instead of milliseconds); therefore, you can readily work with date and time values that have been imported from other sources (and vice versa).In addition, the Date class allows you to set and get date and time values in terms of years, months, days, and so on by using properties such as
fullYear,month, etc. These properties are for your convenience, but the values are stored internally as epoch milliseconds.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Finding the Current Date and Time
- InhaltsvorschauYou want to know the current date and time.Create a new date by using the Date( ) constructor with no parameters. Alternatively, use a CGI script or any other server-side program to return the server time and create a new Date object from that value.The date and time that ActionScript calculates on its own is based on the client computer’s date and time settings. Therefore, if the user’s computer has the incorrect time, so will the Date object. With that caveat in mind, you can retrieve the current client-side date and time by creating a new Date object by using a constructor without parameters, as follows:
// Create a new Date object. var current:Date = new Date( ); // Displays client-side date and time. trace(current);If you have an Internet connection, the Flash movie attempts to retrieve the date and time from a server. This technique can ensure more accurate dates and times. Although the server’s time settings might be inaccurate, at least the time will be consistent for all clients.The basic process when reading the time from a server is as follows:-
Create a CGI script on the web server that outputs the number of seconds since midnight of January 1, 1970 (the epoch).
-
Use a flash.net.URLLoader object from ActionScript to load the epoch seconds.
-
Convert the loaded seconds from a string to a number, multiply by 1,000, and construct a new Date object by passing the value to the constructor.
PHP is a scripting language that can be found on a large number of web hosts. It is quite simple to create a PHP page to output the current time and date as the number of seconds since the epoch. All you need to do is create a PHP document with the following content and upload it to the server:Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Retrieving the Date Values
- InhaltsvorschauYou want to retrieve the year, month, day of month, day of week, hour, minute, second, or millisecond value from a Date object.Use the fullYear, date, month, day, hours, minutes, seconds, or milliseconds properties.The fullYear, date, month, day, hours, minutes, seconds, and milliseconds properties return the values from a Date object:
-
The fullYear property specifies the year as a four-digit value, such as 2010.
-
The date property specifies the day of the month as a value from 1 to 31.
-
The month property specifies the month as an integer from 0 (January) to 11 (December).
-
The day property specifies the day of the week as an integer from 0 (Sunday) to 6 (Saturday).
-
The hours property returns the hours value as an integer from 0 (midnight) to 23 (11 p.m.).
-
The minutes and seconds properties return values from 0 to 59.
-
The milliseconds property returns a value from 0 to 999.
Each of these properties has a UTC (Coordinated Universal Time, also known as Greenwich Mean Time) correspondent. For example, although the hours property returns the current hours value based on the client computer’s clock, the hoursUTC property returns the current hours value in UTC time.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Retrieving the Day or Month Name
- InhaltsvorschauYou want to retrieve the name of the day or month.Create arrays that contain the string values for the names of the days of the week and the names of the months of the year. Use the numeric day and month to extract the string values from the arrays.The ActionScript Date class provides the day and month properties, which return integer values representing the day of the week (from 0 to 6) and the month of the year (from 0 to 11). However, you may want the name of the day or month instead of its zero-relative number. To address this, create arrays containing the names of the days and months. Or, more conveniently, you can use constants of the custom ascb. util.DateFormat class. The constants
DAYS,DAYS_ABBREVIATED,MONTHS, andMONTHS_ABBREVIATEDare each arrays that contain strings that correspond to the numeric values returned by day and month. The actual definitions of those constants are as follows:public static const DAYS:Array = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; public static const DAYSABBREVIATED:Array = ["Sun", "Mon", "Tues", "Wed", "Thurs", "Fri", "Sat"]; public static const MONTHS:Array = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; public static const MONTHSABBREVIATED:Array = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
You can then use those constants as shown in the following example:var example:Date = new Date(2010, 3, 10); trace(DateFormat.DAYS[example.day]); // Displays: Saturday trace(DateFormat.DAYSABBREVIATED[example.day]); // Displays: Sat trace(DateFormat.MONTHS[example.month]); // Displays: April trace(DateFormat.MONTHSABBREVIATED[example.month]); // Displays: Apr
Recipe 14.4Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Formatting the Date and Time
- InhaltsvorschauYou want to display a formatted date and/or time value.Use Date.toString( ), or use the custom DateFormat.format( ) method that returns the date and time as a string in the requested format.The Date.toString( ) method returns a user-friendly string version of the target Date object; for example:
// Displays (something like): Tue Jan 5 14:25:20 GMT-0800 2010 trace((new Date( )).toString( ));
Because ActionScript automatically invokes the toString( ) method on any object used in a string context, you can obtain the same result even if you omit toString( ), as in the following example:// Also displays: Tue Jan 5 14:25:20 GMT-0800 2010 trace(new Date( ));
The Date class doesn’t have any other built-in functionality for formatting a date or time in a customized way. You can, of course, compose a string value, as in the following example:var example:Date = new Date(2010, 0, 5, 10, 25); var formatted:String = (example.month + 1) + "/" + example.fullYear; trace(formatted); // Displays: 1/2010
However, you may have to write a lot of custom code each time you want to display the date and/or time. Instead, you can use the format( ) method of an ascb.util.DateFormat instance. The DateFormat class is a custom class that is specifically designed to assist with formatting dates and times when given a mask. The mask can be composed of any characters, but some characters act like variables. Table 14-1 shows the characters you can use as variables when creating the mask.Table : Date and time symbols Symbol Meaning Example a Lowercase a.m. or p.m. a.m. A Uppercase A.M. or P.M. P.M. d Day of month (leading 0) 01 D Abbreviated day of week Sun F Month January g 12-hour 1 G 24-hour 1 h 12-hour (leading 0) Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Formatting Seconds or Milliseconds as Minutes and Seconds
- InhaltsvorschauYou want to display seconds or milliseconds in minutes and seconds (mm:ss) format.Use either the custom ascb.util.DateFormat.formatSeconds( ) or ascb.util.DateFormat.formatMilliseconds( ) methods.Many values in ActionScript are given in milliseconds or seconds. For example, sound lengths are given in milliseconds. However, in most cases, you want to format the value as minutes and seconds when displaying it to the user. You can accomplish this with a short amount of code. To further simplify things, that code has already been made into static methods of the DateFormat class.The ascb.utils.DateFormat class has two methods that convert a number to the format mm:ss. The formatSeconds( ) method converts seconds to that format, while the formatMilliseconds( ) method converts milliseconds to that format.Recipe 14.4Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- Converting Between DMYHMSM and Epoch Milliseconds
- InhaltsvorschauYou want to convert between DMYHMSM format (days, months, years, hours, minutes, seconds, milliseconds) and epoch milliseconds.Use the time property.Most of us are more comfortable thinking of dates and times in terms of their components such as hours, days, and years than working with epoch milliseconds or seconds. For example, it’s much easier to give the time and date as 10:25 a.m., Tuesday, January 5, 2010 than to discuss the corresponding epoch value of 1,262,715,900,000 milliseconds. However, languages such as ActionScript store times in the epoch milliseconds (or epoch seconds) format. Therefore, it’s important to be able to convert between different formats when displaying dates and times to users, or when sharing dates between applications that use different formats.When constructing a date in ActionScript, you can use the DMYHMSM approach, as follows:
// Construct a date for 10:25 AM, Tuesday, January 5, 2010 var example:Date = new Date(2010, 0, 5, 10, 25);
ActionScript automatically performs the conversion and stores the date as the corresponding epoch milliseconds value. To retrieve that value, all you need to do is call the time property from the Date object, as follows:// For Pacific Standard Time, displays: 1262715900000 // The output may vary depending on your time zone. trace(example.time);
You can pass the epoch seconds value returned by time to another application (such as a CGI script) or use it for performing date mathematics (see Recipe 14.1).On the other hand, you may want to set a date using the epoch milliseconds. For example, in Recipe 14.1 the CGI script returns the current server time to Flash in epoch seconds (which needs to be converted to milliseconds by multiplying by 1,000). Also, when performing date mathematics you may want to set a date according to epoch milliseconds. You have two options for setting a date according to the epoch milliseconds. One choice is to pass the milliseconds value to theEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Using Timers
- InhaltsvorschauYou want to poll a method at a specific interval or add a delay.Use the flash.util.Timer class.The flash.util.Timer class allows you to add timed events or a delay to method calls. You can construct a Timer instance with the constructor. Pass the constructor a number of milliseconds to use as the interval between timer events. The following example instantiates a Timer object that dispatches events every 1,000 milliseconds (1 second):
var timer:Timer = new Timer(1000);
Once you’ve constructed the Timer, you next need to add an event listener to handle the events it dispatches. Timer objects dispatch flash.event.TimerEvent events. The timer event is dispatched at the interval specified when constructing the Timer object (or as set by the delay property). The following example code defines an event listener for the timer event (using the TimerEvent.TIMER constant), which calls a method named onTimer( ):timer.addEventListener(TimerEvent.TIMER, onTimer);
The event handler method is passed a TimerEvent object:function onTimer(event:TimerEvent):void { trace("on timer"); }Timer objects do not start automatically; you must call the start( ) method first:timer.start( );
By default, timers run until stopped by the stop( ) method. However, you can also specify a number of intervals by passing a second parameter to the constructor. The default value of 0 causes the timer to repeat indefinitely, while non-zero values specify a finite number of intervals. The following constructs a timer that has just five intervals:var timer:Timer = new Timer(1000, 5);
You can use a timer with just one interval to add a delay. The following timer code defers the call to the deferredMethod( ) method for five seconds:Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Calculating Elapsed Time or Intervals Between Dates
- InhaltsvorschauYou wan t to calculate an elapsed time, elapsed date, or relative time.For simple elapsed time, you can add and subtract from the epoch milliseconds, or use the value returned by getTimer( ). For more complex conversions, use the methods of the custom DateUtilities class.For simple conversions such as adding or subtracting an hour, day, or week to or from a date, simply add or subtract from the date’s epoch milliseconds value. For this purpose, note that a second is 1,000 milliseconds, a minute is 60,000 milliseconds, an hour is 3,600,000 milliseconds, a week is 604,800,000 milliseconds, and so on. Unless you have a knack for remembering these conversion values, storing them as constants is a convenient option. The constants have already been defined in the custom ascb.util.DateUtilities class as follows:
public static const MILLISECOND:Number = 1; public static const SECOND:Number = MILLISECOND * 1000; public static const MINUTE:Number = SECOND * 60; public static const HOUR:Number = MINUTE * 60; public static const DAY:Number = HOUR * 24; public static const WEEK:Number = DAY * 7;
You can use the Date.time property to retrieve a date’s current value in epoch milliseconds, and then assign a new value to the time property relative to the current value. The following example adds one day to a given Date object:var example:Date = new Date(2010, 0, 5, 10, 25); // Displays: Tue Jan 5 10:25:00 GMT-0800 2010 trace(example); // Add one day to the previous date by setting the new date/time // to the original date/time plus DateUtilities.DAY (the number // of milliseconds in a day). example.time += DateUtilities.DAY; // Displays: Wed Jan 6 10:25:00 GMT-0800 2010 trace(example);You’ll often want to calculate an elapsed time to create a timer for a game or other activity. Calculating the elapsed time is simply a matter of recording the time during initialization and then comparing it to the current time later during execution. You can use aEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Parsing a Date from a String
- InhaltsvorschauYou want to create a Date object from a string.Use the parse( ) method of a DateFormat object.ActionScript does not provide native methods for parsing a string into a Date object, and in many cases, that doesn’t pose any difficulty. For example, Flash Remoting allows you to return native Date objects from other applications. Even if you are not working with Flash Remoting, you can pass values between Flash and other applications using epoch seconds/milliseconds. However, if you need to parse a string into a date, you should use the parse method of the custom ascb.util.DateFormat class. The method takes the string value as a parameter, parses out each of the date’s parts (the year, hour, etc.), and then returns a new Date object.To use the DateFormat class, you need to create an instance with the constructor. When you create the instance, you should pass a mask string to the constructor as a parameter. Recipe 14.4 has more details on creating a mask string:
var formatter:DateFormat = new DateFormat("m/d/Y");Once you’ve created a DateFormat instance, you can next call the parse( ) method. Pass it a string in the format specified by the mask, and it parses the date, returning a new Date instance:// Displays: Sat May 1 00:00:00 GMT-0700 2010 (timezone offset may vary) trace(formatter.parse("05/01/2010")); formatter.mask = "m/d/Y 'at' h:i a"; // Displays: Sat May 1 22:25:00 GMT-0700 2010 (timezone offset may vary) trace(formatter.parse("05/01/2010 at 10:25 PM"));Recipe 14.4Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Chapter 15: Programming Sound
- InhaltsvorschauProper use of sound in an application, game, or web site can greatly enhance the user’s experience. In the Flash IDE, you can import sound into the library, put sound on timeline frames, attach sounds to movie clips, and so on. This chapter covers programming sound with ActionScript 3.0, using the Sound class and its related classes.The Sound class is set up to load and stream external MP3 sound files. Since the files aren’t embedded in the .swf and are being loaded from an external URL, the domain security restrictions outlined in Chapter 3 apply.Classes covered in this chapter include:
-
Sound
-
SoundChannel
-
SoundLoaderContext
-
SoundMixer
-
SoundTransform
These are all part of the flash.media package, so as your first order of business, make sure that you importflash.media.Soundin each example as well as any of the other classes the example uses.You want to load into your .swf and have it available to the application.Create a Sound object and load an external sound file into it.Creating a Sound object is as easy as making an instance of any class. First, though, make sure the Sound class is imported:import flash.media.Sound;
and then just create an instance of the Sound class:_sound = new Sound( );
Now of course, you need to give it a sound file to play. As mentioned earlier, this will be an external MP3 file, such as a song. For all of the examples in this chapter, it’s assumed that you have an MP3 file named song.mp3, and that this is stored in the same directory as the .swf on your server or hard drive.To load a sound file into your Sound object, first create aEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Introduction
- InhaltsvorschauProper use of sound in an application, game, or web site can greatly enhance the user’s experience. In the Flash IDE, you can import sound into the library, put sound on timeline frames, attach sounds to movie clips, and so on. This chapter covers programming sound with ActionScript 3.0, using the Sound class and its related classes.The Sound class is set up to load and stream external MP3 sound files. Since the files aren’t embedded in the .swf and are being loaded from an external URL, the domain security restrictions outlined in Chapter 3 apply.Classes covered in this chapter include:
-
Sound
-
SoundChannel
-
SoundLoaderContext
-
SoundMixer
-
SoundTransform
These are all part of the flash.media package, so as your first order of business, make sure that you importflash.media.Soundin each example as well as any of the other classes the example uses.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Creating a Sound Object and Loading a Sound
- InhaltsvorschauYou want to load into your .swf and have it available to the application.Create a Sound object and load an external sound file into it.Creating a Sound object is as easy as making an instance of any class. First, though, make sure the Sound class is imported:
import flash.media.Sound;
and then just create an instance of the Sound class:_sound = new Sound( );
Now of course, you need to give it a sound file to play. As mentioned earlier, this will be an external MP3 file, such as a song. For all of the examples in this chapter, it’s assumed that you have an MP3 file named song.mp3, and that this is stored in the same directory as the .swf on your server or hard drive.To load a sound file into your Sound object, first create a URLRequest object (you’ll need to import flash.net.URLRequest), passing in the string containing the path to the MP3 file:soundFile = new URLRequest("song.mp3");You can then pass this to the load method of your Sound object:_sound.load(soundFile);
You can even shortcut these last two steps, as seen in the following class example:package { import flash.display.Sprite; import flash.media.Sound; import flash.net.URLRequest; public class LoadSoundExample extends Sprite { private var _sound:Sound; public function LoadSoundExample ( ) { _sound = new Sound( ); _sound.load(new URLRequest("song.mp3")); } } }The class now has a property,_sound, which you can use any time you need to play that sound. Note that the sound does not actually start playing yet. You have merely set it up and started the sound information coming in. See Recipe 15.2 for information on how to control a sound’s playing.An even quicker way is to pass theEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Starting and Stopping a Sound
- InhaltsvorschauYou’ve created a Sound object and started streaming a sound file into it. Now you want to play it and eventually stop it.Use the play( ) method to start the sound playing. Use the close( ) method to stop the sound from streaming.Playing a sound which has been loaded into a Sound object is very easy. Simply call the play( ) method of that Sound object, like so:
_sound = new Sound(new URLRequest("song.mp3")); _sound.play( );It is that simple. There are some additional optional parameters to the play( ) method, which are covered in Recipes 15.1 and 15.10.The close( ) method of the Sound object not only stops the sound from playing, but also stops the streaming of the sound file. To play that sound again, call the load( ) method to restart loading the sound data. The close( ) method should be called only when you are sure you are finished with that particular sound. Recipe 15.10 discusses a way to stop the sound from playing without stopping the stream, using the SoundChannel class.Recipe 15.1 for information on how to load external sound files and Recipe 15.10.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Setting the Buffer for a Sound
- InhaltsvorschauYou want to ensure that a streaming sound plays smoothly.Set a buffer time by using the SoundLoaderContext class.The Sound class streams audio as it plays, which means that a sound starts playing before it is fully downloaded. This is especially useful for larger sound files, such as full songs, which can be several megabytes in size.Depending on how your sound is encoded and the available bandwidth, a sound may be playing faster than it is downloading. In this case, the sound may pause while it waits for more sound data to load in. To safeguard against this, you can set a buffer. This causes the Sound object to pre-load a certain amount of sound data before it starts playing. Then, if there is a momentary slowdown in bandwidth, the sound can keep playing the buffered data without pausing.By default, a Sound object creates a one-second buffer when you tell it to load a sound file. In other words, even if you tell it to play immediately, the Sound object waits until at least one second’s worth of sound data has come in. Additionally, if that buffer is used up and the sound needs to stop to wait for more data, it refills that one-second buffer before it resumes playing again.If you are unsure of network conditions or have sound files that were encoded at a high bitrate (requiring more bits of information per second of playing time), then you may want to increase the size of this buffer to ensure smoother playback. You do this by creating a SoundLoaderContext object, passing in the size of the buffer, in milliseconds, to the constructor. For example, if you wanted to create a five-second buffer, you would do the following:
buffer = new SoundLoaderContext(5000);
You can use this object for either method of loading a sound—in the constructor of theEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Offsetting the Start of a Sound
- InhaltsvorschauYou want a sound to start playing, not from the start of the sound, but at a position some ways into it.Pass a start time to the play( ) method.There may be instances when you want to start playing a sound file, but not from the very beginning of the sound. In other words, you want to cut off some amount from the start of the sound and play it from that offset point. The Sound object gives you very precise control so you can pinpoint the exact place where a sound will start playing, right down to the millisecond.If you call a Sound object’s play( ) method without any parameters, it starts playing from the very beginning. But you can pass it an optional parameter that is the number of milliseconds into the sound at which you want it to start. For example, the following causes the sound to start playing at exactly 5.5 seconds after its beginning point:
_sound.play(5500);
This particularly comes in handy when you have a sound file that has some introductory material at the beginning that you want to skip over. If you can’t edit the sound file to cut that part out, all you need to do is set the start time and skip over the initial portion.Another example would be to create a system of cue points in the sound. Say you had a recording of a speech and you wanted to allow users to listen to any of several portions of that speech. Taking note of the points at which each portion begins, you can set these up as cue point values in an array. Now, by specifying which cue point to start playing the sound from, you can get the start time from the array and pass that to the play( ) method. The following class demonstrates a simple example of this:package { import flash.display.Sprite; import flash.media.Sound; import flash.net.URLRequest; public class CuePoints extends Sprite { private var _sound:Sound; private var _cuePoints:Array; public function CuePoints( ) { _cuePoints = [0, 10000, 30000, 68000, 120000]; _sound = new Sound(new URLRequest("song.mp3")); // Play from the third cuepoint (30 seconds in) playCuePoint(2); } public function playCuePoint(index:int):void { _sound.play(_cuePoints[index]); } } }Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Playing a Sound Multiple Times (Looping)
- InhaltsvorschauYou want to play a sound file more than once, or have it play over and over in a continuous loop.Set a looping value in the play( ) method.When you play a sound, it only plays once—from beginning to end—by default. There may be cases when you want to have the sound play more than once, or even play continuously. For example, you may have a short music loop for the background to a game or for a web site. You can set this loop to play continuously so it sounds like one long song.The way to set the number of loops (or times) to play is by passing in a value as the second parameter of the play( ) method. Of course, if you do this, you’ll also have to set a value for the optional first parameter of the start offset (see Recipe 15.1). If you don’t want to offset the start of the sound, but want to use the loop parameter, just pass zero as the first parameter, like so:
_sound.play(0, 3);
This plays the sound file from the very beginning (zero offset) and loops it three times.The minimum sensible value you can set for a loop is one, which causes the sound to play only once. If you pass in zero (or even a negative number), the sound still plays only one time.There is no automatic way to cause the sound to loop forever; however, you can pass a very high value. An easy solution is to pass inint.MAX_VALUE, which is the highest value that an integer variable can hold, and is equal to 2,147,483,647. Even if your sound was only one second long, this would cause it to play for almost 70 years, which is pretty safe to call “continuously.”Recipes 15.1 and 15.2Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Getting the Size of a Sound File
- InhaltsvorschauYou want to know the total size of the MP3 audio file you are loading, as well as the amount that has downloaded so far (so you can create a visual streaming indicator).Access the bytesTotal and bytesLoaded properties of the Sound object.When streaming an audio file, it’s often a good idea to let the user know how much data has been loaded. The Flash Player loads the sound as fast as it can, and plays the sound at its encoded rate. Ideally, the sound data will load faster than the sound is playing so there won’t be a point at which the audio stops playing to load more data. However, in cases of poor connectivity or low bandwidth, and when sounds have been encoded with a high bitrate, the Flash Player may be struggling to keep enough sound data buffered so the sound doesn’t stop.Therefore, it’s a good idea to give the user some sort of visual representation for the amount of buffered sound data, alongside the progress of the sound as it plays. You’ve probably seen this in many types of streaming media players, such as Windows Media Player or QuickTime Player. Usually there’s a progress bar tracking the song as it plays. The background of the bar might be white. On top of that would be a growing black bar representing the progress of the song. Additionally, you might have a gray bar that indicates the buffered amount. As long as the gray bar (buffer) stays ahead of the black one (play position), you know you’ll have smooth playback. When it catches up, the media stops playing while the gray bar moves ahead, buffering more data. When it has enough, the media starts again, and the black bar starts moving again, and hopefully the gray has enough of a head start this time.This recipe covers how to create that gray bar, using two properties of a Sound object:Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- Reading the ID3 Tag of a Sound File
- InhaltsvorschauYou want to access information about the MP3 file you are playing, such as the name of the song, artist, album, genre, etc.Read the id3 property of the Sound object.MP3 audio files are able to contain an abundance of metadata about the sound. This is most often used in music files to record the name of the song, the artist, album, genre, year of release, composer, etc. How much information is actually included in these tags depends on who encoded or tagged the file. In most cases though, you’ll at least be able to get at the songname and artist tag.This data is available to you in ActionScript through the id3 property of a Sound object.This property is an instance of the flash.media.ID3Info class, which contains the following properties:
-
album -
artist -
comment -
genre -
songName -
track -
year
So, to read the song’s name, you would access it as follows:_sound.id3.songName
There is just one catch to all of this, though: you can’t access these id3 tags until they have actually downloaded into your .swf. If you try to read a tag immediately after you create your Sound object or call play( ), it won’t be defined. Factually, the request for the sound file has probably not even reached the server at that point, so of course there will be no tag data available.So, how do you know when this id3 data is available? Fortunately, the Sound object has an ID3 event that you can listen for. When this event fires, it is safe to read the id3 tags. The Sound class extends the EventDispatcher class, so you can use add- EventDispatcherEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Find Out When a Sound Finishes Playing
- InhaltsvorschauYou’ve started playing a sound file and need to know when it has finished playing.Listen for the soundComplete event.There are many cases when you might need to know when a sound is finished playing. For example, if have an audio introduction that you want to play before a user moves onto the next section of a site, you will want to know when it is safe to go to the next section. Or perhaps you have a music player with a playlist of songs. You’ll want to know when each song is complete so you can start the next one.For this recipe, and the next few, you’ll be working with another class in the flash.media package, SoundChannel. When you call a Sound object’s play( ) method, it returns a SoundChannel object. Thus, each sound playing in a .swf is represented by a single SoundChannel object. These channels are mixed together to produce the final audio output.When a sound file has finished playing, its corresponding SoundChannel object fires a soundComplete event. This is defined as flash.events.Event.SOUND_COMPLETE. You can add a listener to the SoundChannel object and supply a handler method, which is called when the sound has finished playing.The following example sets up a simple playlist:
package { import flash.display.Sprite; import flash.media.Sound; import flash.net.URLRequest; import flash.events.Event; import flash.media.SoundChannel; public class PlayList extends Sprite { private var _sound:Sound; private var _channel:SoundChannel; private var _playList:Array; // the list of songs private var _index:int = 0; // the current song public function PlayList( ) { // Create the playlist and start playing _playList = ["song1.mp3", "song2.mp3", "song3.mp3"]; playNextSong( ); } private function playNextSong( ):void { // If there are still songs in the playlist if(_index < _playList.length) { // Create a new Sound object, load and play it // _playList[_index] contains the name and path of // the next song _sound = new Sound( ); _sound.load(new URLRequest(_playList[_index])); _channel = _sound.play( ); // Add the listener to the channel _channel.addEventListener(Event.SOUND_COMPLETE, onComplete); // Increase the counter _index++; } } public function onComplete(event:Event):void { playNextSong( ); } } }Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Tracking the Progress of a Playing Sound
- InhaltsvorschauYou want to know where the playhead is in the current song so you can see how much of the song has played, in relation to the full song.Use Sound.length to determine how long a song is, and SoundChannel.position to determine how much of it has played.Recipe 15.6 discussed how to add a progress bar that not only shows the playing position of a sound file, but also how much of that file has been loaded into the player. That recipe created the part of the bar that showed how much of the song has loaded.This recipe covers the other part, showing you how to track a sound’s progress as it plays. To do this, you’ll need to know two things: the length of the sound and its current playing position. Although it may seem counterintuitive, these two properties are found in two different classes. The length of the sound is a property of the Sound object, and the playing position is part of the SoundChannel. Similar to how the buffering progress bar was created, these two values can be compared against each other to get the percentage of the sound that has played.Unfortunately, it gets just a bit more complex than the buffering bar. The problem is that the length property isn’t accurate until the sound file is fully loaded. It actually just shows the length of the loaded data. So, for example, if 10 percent of a 10-minute audio file has loaded so far, then length would report that the file was 1 minute long. (Actually, both length and position report the time in milliseconds, but you can convert that to minutes and seconds if you needed to display the numbers.)Fortunately, you can do some simple math to get an estimate of the sound file’s actual length. Since length reports a fraction of the actual length, if you divide it by that fraction, the result is very close to the true time of the sound. Taking the example just mentioned,Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- Pausing and Restarting a Sound
- InhaltsvorschauYou want to pause a sound and restart it later from where it stopped playing.Take note of the position property of the sound’s SoundChannel. When you restart the sound, use that value as an offset.As noted in Recipe 15.2, you can call the close( ) method of a Sound object to make it stop playing. However, this also stops the sound from streaming, so to replay it, you’ll need to re-call the load( ) method.Fortunately, the SoundChannel class offers a stop( ) method, which causes the sound to stop playing without affecting the loading. To restart the sound, just call the play( ) method again.You should note, however, that the play( ) method causes the sound to start from the beginning. This is the expected behavior for a “stop” button, as seen on many media players. Creating a “pause” button takes a bit more work. The strategy is to set up a handler method that’s called when a pause button is pressed. In this function, read and store the current position of the SoundChannel, which gives you the time in milliseconds from the sound’s beginning. Store this in a class variable so it can be accessed later. At this point, the pause button becomes a play button. When pressed again, call the play( ) method of the Sound object, passing in the saved position. This causes the sound to play from that point, which is the exact point at which it stopped. The following example demonstrates this strategy:
package { import flash.display.Sprite; import flash.media.Sound; import flash.media.SoundChannel; import flash.net.URLRequest; import flash.events.Event; import flash.display.Sprite; import flash.events.MouseEvent; public class PlayPause extends Sprite { private var _sound:Sound; private var _channel:SoundChannel; private var _playPauseButton:Sprite; private var _playing:Boolean = false; private var _position:int; public function PlayPause( ) { // Create sound and start it _sound = new Sound(new URLRequest("song.mp3")); _channel = _sound.play( ); _playing = true; // A sprite to use as a Play/Pause button _playPauseButton = new Sprite( ); addChild(_playPauseButton); _playPauseButton.x = 10; _playPauseButton.y = 20; _playPauseButton.graphics.beginFill(0xcccccc); _playPauseButton.graphics.drawRect(0, 0, 20, 20); _playPauseButton.addEventListener(MouseEvent.MOUSE_UP, onPlayPause); } public function onPlayPause(event:MouseEvent):void { // If playing, stop. Take note of position if(_playing) { _position = _channel.position; _channel.stop( ); } else { // If not playing, re-start it at // last known position _channel = _sound.play(_position); } _playing = !_playing; } } }Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Reading the Level of a Sound
- InhaltsvorschauYou want to know how loud a currently playing sound is.Access the SoundChannel.leftPeak and SoundChannel.rightPeak properties.Any sound, as it is playing, goes through various levels of loudness and softness. This is known as its amplitude. ActionScript 3.0 lets you access the amplitude for the left and right channels of a stereo sound separately. These are the leftPeak and rightPeak properties of the SoundChannel object that is created when you start playing a sound.These values are in a range from 0.0 to 1.0, with 1.0 being the maximum amplitude. Don’t confuse this with volume, which can be an overall setting for a sound, and is controlled via the SoundTransorm object (see Recipe 15.14). This is the level of sound volume at a particular instance, and it varies constantly as the sound plays.The following example reads these values and creates two bars, the lengths of which are based on the current amplitude of each channel on each frame:
package { import flash.display.Sprite; import flash.media.Sound; import flash.media.SoundChannel; import flash.net.URLRequest; import flash.events.Event; public class SoundLevels extends Sprite { private var _sound:Sound; private var _channel:SoundChannel; public function SoundLevels( ) { addEventListener(Event.ENTER_FRAME, onEnterFrame); _sound = new Sound(new URLRequest("song.mp3")); _channel = _sound.play( ); } public function onEnterFrame(event:Event):void { var leftLevel:Number = _channel.leftPeak * 100; var rightLevel:Number = _channel.rightPeak * 100; graphics.clear( ); graphics.beginFill(0xcccccc); graphics.drawRect(10, 10, leftLevel, 10); graphics.endFill( ); graphics.beginFill(0xcccccc); graphics.drawRect(10, 25, rightLevel, 10); graphics.endFill( ); } } }Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Stopping All Sounds
- InhaltsvorschauYou want to stop all currently playing sounds.Use the stopAll( ) method of the SoundMixer object.As mentioned earlier, whenever you start playing a sound, it creates a SoundChannel object. You can play multiple sounds in a .swf, and each one will be assigned to a separate sound channel. Some aspects of a sound are controlled via the Sound object itself, some from the sound channel. In the end, all of the currently playing channels are mixed together to create the final sound coming from the speakers. The object responsible for this is the SoundMixer object. Its properties and methods apply to all the sounds in the movie as they are mixed together.One of these methods is the stopAll( ) method. As expected, this stops every currently playing sound in the .swf.Although sound can greatly enhance the experience of a web site, game, etc., you should always give the user the option to turn off the sound. The stopAll( ) method is the simplest way to do this. It is a static method of the SoundMixer class, so you can call it directly from there. Usually this would be done in an event handler attached to a button or sprite, like so:
public function stopSounds(event:Event):void { SoundMixer.stopAll( ); }Recipe 15.2Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Reading the Sound Spectrum
- InhaltsvorschauYou want to visually represent the sound wave of the sounds playing in your .swf.Use SoundMixer.computeSpectrum( ) to fill a byte array with the spectrum data of the sound playing in the .swf. Read the values of this array to create a visualization of that data.One of the most exciting additions to the sound capabilities in ActionScript 3.0 is the ability to access sound spectrum data. Throughout the years and versions of Flash, developers have yearned to get at this data. Some third-party tools read this data in and created a separate text file containing the values of the sound spectrum data. This file could be read in and synchronized to the sound. However, these solutions were complex to work with and not very efficient. Now that this feature is built into the SoundMixer class, and with the addition of the new ByteArray class, you can easily display this data with just a few lines of code.First, let’s cover the ByteArray class. This new special class in ActionScript 3.0 is used to handle blocks of binary data in a highly compact, efficient, and optimized way. It is part of the flash.utils package. Essentially, it is what it sounds like: an array of bytes. But its methods allow for fast manipulation and access of its data—much faster than a traditional ActionScript array.For use in computing the sound spectrum, you first need to create an empty ByteArray, as shown in the following example:
var spectrum:ByteArray = new ByteArray( );
This ByteArray is then passed into SoundMixer.computeSpectrum( ). This method takes a snapshot of the sound as it’s playing and calculates the current sound wave on both the left and right channels. It breaks this into 256 values on each channel, each from -1.0 to 1.0. It stores these values in the emptyEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Changing the Volume or Pan of a Sound
- InhaltsvorschauYou want to change the volume of a sound, making it softer or louder, or set the pan (amount of left/right balance) of a sound.Create a new SoundTransform object, specifying the volume at which you want the sound to play, or the amount and direction of panning you want to apply. Pass this to the soundTransform property of the SoundChannel object associated with the sound you want to control.In previous versions of ActionScript, you could set the volume and panning of a sound directly on the Sound object itself. Now these aspects of the sound playback are abstracted into the SoundTransform class.A SoundChannel object has a soundTransform property, which is an instance of the SoundTransform class. To change a sound’s volume or panning, create a new SoundTransform object and set the desired values. Next, set the SoundChannel’s soundTransform property to this new object. For example, the following sets the sound volume to 50 percent:
var _sound:Sound = new Sound(new URLRequest("song.mp3")); var channel:SoundChannel = _sound.play( ); var transform:SoundTransform = new SoundTransform( ); transform.volume = .5; channel.soundTransform = transform;As you can gather, the volume can range from 0.0 (silent) to 1.0 (full volume). Similarly, you can set the panning of a sound:var channel:SoundChannel = _sound.play( ); var transform:SoundTransform = new SoundTransform( ); transform.pan = -1.0; channel.soundTransform = transform;
This sets the sound to play only in the left speaker, as the values here can range from -1.0 (full left) to 1.0 (full right).You can also pass the volume and pan amounts straight to the SoundTransform’s constructor, like so:var channel:SoundChannel = _sound.play( ); var transform:SoundTransform = new SoundTransform(.5, -1.0); channel.soundTransform = transform;
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Creating a Sound Application
- InhaltsvorschauYou want to create a full-featured sound application, such as a streaming MP3 player.Apply the other recipes in this chapter to play a streaming sound and add as many features as you want.This recipe combines many of the techniques shown throughout this chapter, integrated into a single application. There is much more that could be done with this, but it should give you a start at seeing how to use all these features together.
package { import flash.display.Sprite; import flash.display.Stage; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.text.TextField; import flash.events.Event; import flash.events.MouseEvent; import flash.events.TimerEvent; import flash.media.Sound; import flash.media.SoundChannel; import flash.media.SoundTransform; import flash.net.URLRequest; import flash.text.TextFormat; import flash.utils.Timer; public class CookBookPlayer extends Sprite { private var _channel:SoundChannel; private var _displayText:TextField; private var _sound:Sound; private var _panControl:PanControl; private var _playing:Boolean = false; private var _playPauseButton:Sprite; private var _position:int = 0; private var _spectrumGraph:SpectrumGraph; private var _volumeControl:VolumeControl; public function CookBookPlayer( ) { // Stage alignment stage.scaleMode = flash.display.StageScaleMode.NO_SCALE; stage.align = flash.display.StageAlign.TOP_LEFT; // Enter frame listener var timer:Timer = new Timer(20); timer.addEventListener(TimerEvent.TIMER, onTimer); timer.start( ); _playing = true; // Display a text field _displayText = new TextField( ); addChild(_displayText); _displayText.x = 10; _displayText.y = 17; _displayText.width = 256; _displayText.height = 14; // Create a sound object _sound = new Sound(new URLRequest(""http://www.rightactionscript.com samplefiles/sample.mp3"")); _sound.addEventListener(Event.ID3, onID3); _channel = _sound.play( ); // Create a bitmap for spectrum display _spectrumGraph = new SpectrumGraph( ); _spectrumGraph.x = 10; _spectrumGraph.y = 33; addChild(_spectrumGraph); // Create the Play and Pause buttons _playPauseButton = new PlayButton( ); _playPauseButton.x = 10; _playPauseButton.y = 68; addChild(_playPauseButton); _playPauseButton.addEventListener(MouseEvent.MOUSE_UP, onPlayPause); // Create volume and pan controls _volumeControl = new VolumeControl( ); _volumeControl.x = 45; _volumeControl.y = 68; addChild(_volumeControl); _volumeControl.addEventListener(Event.CHANGE, onTransform); _panControl = new PanControl( ); _panControl.x = 164; _panControl.y = 68; addChild(_panControl); _panControl.addEventListener(Event.CHANGE, onTransform); } public function onTransform(event:Event):void { // Get volume and pan data from controls // and apply to a new SoundTransform object _channel.soundTransform = new SoundTransform( _volumeControl.volume, _panControl.pan); } public function onPlayPause(event:MouseEvent):void { // If playing, stop and record that position if(_playing) { _position = _channel.position; _channel.stop( ); } else { // Else, restart at the saved position _channel = _sound.play(_position); } _playing = !_playing; } public function onID3(event:Event):void { // Display selected id3 tags in the text field _displayText.text = _sound.id3.artist + " : " + _sound.id3.songName; _displayText.setTextFormat( new TextFormat("_typewriter", 8, 0)); } public function onTimer(event:TimerEvent):void { var barWidth:int = 256; var barHeight:int = 5; var loaded:int = _sound.bytesLoaded; var total:int = _sound.bytesTotal; var length:int = _sound.length; var position:int = _channel.position; // Draw a background bar graphics.clear( ); graphics.beginFill(0xFFFFFF); graphics.drawRect(10, 10, barWidth, barHeight); graphics.endFill( ); if(total > 0) { // The percent of the sound that has loaded var percentBuffered:Number = loaded / total; // Draw a bar that represents the percent of // the sound that has loaded graphics.beginFill(0xCCCCCC); graphics.drawRect(10, 10, barWidth * percentBuffered, barHeight); graphics.endFill( ); // Correct the sound length calculation length /= percentBuffered; // The percent of the sound that has played var percentPlayed:Number = position / length; // Draw a bar that represents the percent of // the sound that has played graphics.beginFill(0x666666); graphics.drawRect(10, 10, barWidth * percentPlayed, barHeight); graphics.endFill( ); _spectrumGraph.update( ); } } } } // "helper classes" // (This is an outside package, but it's available to classes // in the same file) import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.filters.DropShadowFilter; import flash.geom.Rectangle; import flash.media.SoundMixer; import flash.utils.ByteArray; class PlayButton extends Sprite { public function PlayButton( ) { // Draw the Play/Pause graphic graphics.beginFill(0xcccccc); graphics.drawRoundRect(0, 0, 20, 16, 4, 4); graphics.endFill( ); graphics.beginFill(0x333333); graphics.moveTo(4, 4); graphics.lineTo(8, 8); graphics.lineTo(4, 12); graphics.lineTo(4, 4); graphics.drawRect(10, 4, 2, 8); graphics.drawRect(14, 4, 2, 8); graphics.endFill( ); } } class SpectrumGraph extends Sprite { private var _spectrumBMP:BitmapData; public function SpectrumGraph( ) { // Bitmap to draw spectrum data in _spectrumBMP = new BitmapData(256, 30, true, 0x00000000); var bitmap:Bitmap = new Bitmap(_spectrumBMP); bitmap.filters = [new DropShadowFilter(3, 45, 0, 1, 3, 2, .3, 3)]; addChild(bitmap); } public function update( ):void { // Get spectrum data var spectrum:ByteArray = new ByteArray( ); SoundMixer.computeSpectrum(spectrum); // Draw to bitmap _spectrumBMP.fillRect(_spectrumBMP.rect, 0xff666666); _spectrumBMP.fillRect(new Rectangle(1, 1, 254, 28), 0x00000000); for(var i:int=0;i<256;i++) { _spectrumBMP.setPixel32(i, 10 + spectrum.readFloat( ) * 10, 0xff000000); } for(var i:int=0;i<256;i++) { _spectrumBMP.setPixel32(i, 20 + spectrum.readFloat( ) * 10, 0xff000000); } } } class VolumeControl extends Sprite { public var volume:Number = 1.0; public function VolumeControl( ) { addEventListener(MouseEvent.CLICK, onClick); draw( ); } public function onClick(event:MouseEvent):void { // When user clicks the bar, set the volume volume = event.localX / 100; draw( ); dispatchEvent(new Event(Event.CHANGE)); } private function draw( ):void { // Draw a bar and the current volume position graphics.beginFill(0xcccccc); graphics.drawRect(0, 0, 102, 16); graphics.endFill( ); graphics.beginFill(0x000000); graphics.drawRect(volume * 100, 0, 2, 16); } } class PanControl extends Sprite { public var pan:Number = 0; public function PanControl( ) { addEventListener(MouseEvent.CLICK, onClick); draw( ); } public function onClick(event:MouseEvent):void { // When the user clicks bar, set pan pan = event.localX / 50 - 1; draw( ); dispatchEvent(new Event(Event.CHANGE)); } private function draw( ):void { // Draw the bar and current pan position graphics.beginFill(0xcccccc); graphics.drawRect(0, 0, 102, 16); graphics.endFill( ); graphics.beginFill(0x000000); graphics.drawRect(50 + pan * 50, 0, 2, 16); } }Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Chapter 16: Video
- InhaltsvorschauThe Flash Player is capable of playing back video. Although it’s possible to embed video content within an .swf file, most Flash video content is stored in Flash video files (.flv files) and loaded into the Flash Player at runtime using ActionScript. By loading .flv files at runtime, you have smaller .swf files, more flexible content management, and greater control over the loading and playback of the video content.Flash video loaded from .flv files has two faces: progressive download and streaming. Streaming .flv video requires a streaming server, such as Flash Media Server. In contrast, progressive download doesn’t require any additional software. However, for the most part, the ActionScript required to work with streaming and progressive download video is identical. The recipes in this chapter discuss how to work with progressive download video and focus exclusively on working with .flv files.You want to load and playback progressive download Flash video.Use a NetStream object to load and playback the video and use a Video object to display the video.ActionScript 3.0 requires several classes working together to load and playback Flash video. You must use a NetStream object to load the video and control the playback; however, the NetStream class is only concerned with moving data, it doesn’t know how to render the data as a video. For that you have to use a Video object. The Video object allows you to pass it a NetStream object, which then uses the NetStream data to render the video to the screen.The NetStream constructor requires that you pass it a NetConnection object. The NetConnection object determines the origin of the data that the NetStream object handles. When the Flash video streams from a Flash Communication Server or Flash Media Server, theEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- Introduction
- InhaltsvorschauThe Flash Player is capable of playing back video. Although it’s possible to embed video content within an .swf file, most Flash video content is stored in Flash video files (.flv files) and loaded into the Flash Player at runtime using ActionScript. By loading .flv files at runtime, you have smaller .swf files, more flexible content management, and greater control over the loading and playback of the video content.Flash video loaded from .flv files has two faces: progressive download and streaming. Streaming .flv video requires a streaming server, such as Flash Media Server. In contrast, progressive download doesn’t require any additional software. However, for the most part, the ActionScript required to work with streaming and progressive download video is identical. The recipes in this chapter discuss how to work with progressive download video and focus exclusively on working with .flv files.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- Loading and Playing Back Video
- InhaltsvorschauYou want to load and playback progressive download Flash video.Use a NetStream object to load and playback the video and use a Video object to display the video.ActionScript 3.0 requires several classes working together to load and playback Flash video. You must use a NetStream object to load the video and control the playback; however, the NetStream class is only concerned with moving data, it doesn’t know how to render the data as a video. For that you have to use a Video object. The Video object allows you to pass it a NetStream object, which then uses the NetStream data to render the video to the screen.The NetStream constructor requires that you pass it a NetConnection object. The NetConnection object determines the origin of the data that the NetStream object handles. When the Flash video streams from a Flash Communication Server or Flash Media Server, the NetConnection object points to the server. However, for progressive download video content the NetConnection object uses a null connection string. The following code constructs a NetConnection object and initializes it for use with progressive download video. Note that the code assumes you’ve imported the flash.net.NetConnection class:
var videoConnection:NetConnection = new NetConnection( ); videoConnection.connect(null);
Once you’ve constructed a NetConnection object and called the connect( ) method with anullvalue, construct the NetStream object, and then pass the NetStream constructor a reference to the NetConnection object. The following code constructs a NetStream object (assuming you’ve imported flash.net.NetStream):var videoStream:NetStream = new NetStream(videoConnection);
Once you’ve constructed the NetStream object, add a Video object, and associate the NetStreamEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Controlling Video Sound
- InhaltsvorschauYou want to control the volume and pan transform of the sound portion of the video.Use the
soundTransformproperty of the NetStream object.If a Flash video has an audio track, the audio plays back automatically along with the video. If you want to manage the volume or pan transform of the sound you can use thesoundTransformproperty of the NetStream object to retrieve a reference to the SoundTransform object associated with the audio. For more details on working with SoundTransform objects, see Recipe 15.14.Recipe 15.14Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Reading Playback Time
- InhaltsvorschauYou want to read the current playback time of a video.Use the
timeproperty of the NetStream object.Thetimeproperty of the NetStream class is a read-only property that reports the playback time of the video. The value is in seconds from the start of the video. The following displays the playback time of a video in a text field:textField.text = videoStream.time + " seconds";
Note that the value is not rounded to the nearest whole number. That means you can have values such as 1 as well as values such as 5.235. If you need whole numbers, you can use Math.round( ), Math.floor( ), or Math.ceil( ).Since thetimeproperty is read-only, you cannot use it to control playback. If you want to control playback, use the seek( ) method as described in Recipe 16.5.Recipes 4.3 and 16.5Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Reading Video Duration
- InhaltsvorschauYou want to read the total length (duration) of a video.Use an onMetaData( ) callback and read the
durationmetadata value.The NetStream class does not define a property that reports the total length of a Flash video. However, in most cases, it is possible to read that value from the FLV file itself. FLV files can contain metadata, and almost all video encoders include adurationmetadata value, which stores the length of the video in seconds (which can be fractions of seconds). Assuming the FLV has adurationmetadata value, you can read that value with ActionScript.When a NetStream object is loading an FLV file, it automatically calls an onMetaData( ) callback method when the metadata has loaded. The callback model differs from the standard event model used by most of the ActionScript 3.0 APIs. In most cases in which you work with events you add a listener using addEventListener( ). However, in the case of metadata events you must define an onMetaData( ) method for an object and then assign that object to theclientproperty of the NetStream object. The method is automatically passed an associative array parameter typed as Object that contains properties and values corresponding to each of the metadata properties that have been read from the FLV. The following example uses trace( ) to display thedurationmetadata value of a video clip:var client:Object = new Object( ); client.onMetaData = function(metadata:Object):void { trace(metadata.duration); }; videoStream.client = client;In practice, the preceding example isn’t all that useful. Rather, you’re more likely to assign a function reference to theonMetaDataproperty of the NetStream object. When the function is called, it is called with the correct scope. The following example class loads, plays back a video, and displays the playback time and duration:Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Controlling Playback Time
- InhaltsvorschauYou want to control the playback of a video.Use the seek( ) method of the NetStream object.Although you may assume you can set the playback time by assigning a value to the
timeproperty of the NetStream object that controls the video, that won’t work. As mentioned in Recipe 16.3, thetimeproperty is read-only. Rather, you must use the seek( ) method. The seek( ) method requires one parameter to specify the number of seconds from the start of the video to which you want to move the playback. The following example seeks five seconds from the start of the video before starting the playback:videoStream.seek(5);
When using seek( ) with progressive download video, you can seek to only a part of the video that has downloaded. For example, if half of a 60-second video has downloaded, you can seek to 10 seconds, but you cannot seek to 50 seconds.When you use seek( ), Flash Player jumps to the nearest video keyframe to the value you specify. Videos are encoded with different keyframe rates. Higher keyframe rates have larger bandwidth requirements than lower keyframe rates. However, higher keyframe rates enables greater granularity when seeking.Recipe 16.12Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Scaling Video
- InhaltsvorschauYou want to change the dimensions of the video display.Set the
widthandheightproperties of the Video object. If you want the video to playback at the dimensions at which it was encoded, use thevideoWidthandvideoHeightvalues.The dimensions at which a video plays back are determined by thewidthandheightof the Video object. When you construct a Video object, you can specify the display’s initial width and height; for example, the following constructs a Video object that is 160×120 pixels:var video:Video = new Video(160, 120);
However, you can still change the dimensions after the object is constructed by using thewidthandheightproperties. The following doubles the dimensions of the Video object constructed in the preceding example:video.width = 320; video.height = 240;
The Video class also defines two read-only properties,videoWidthandvideoHeight, which return the width and height at which the video was encoded. You can use thevideoWidthandvideoHeightproperties to set thewidthandheightof the Video object, as follows:video.width = video.videoWidth; video.height = video.videoHeight;
However, note that thevideoWidthandvideoHeightproperties are not correctly defined until the FLV has started to download. Therefore, if you want to set the width and height of the Video object based on the encoded dimensions, you must wait until thevideoWidthandvideoHeightproperties are correctly defined. You can use anetStatusevent listener for that purpose:videoStream.addEventListener(NetStatusEvent.NET_STATUS, onStatus);
Then define the listener with anifstatement that tests forvideoWidthandvideoHeightgreater than 0, as well as width and height values not equal tovideoWidthandvideoHeight. Since thevideoWidthandvideoHeightEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Managing and Monitoring Buffering and Loading
- InhaltsvorschauYou want to manage video buffering and monitor the progress of a video as it downloads.Use the
bufferTimeproperty to set the number of seconds that must buffer before playback starts, and then usebytesLoadedandbytesTotalto monitor the download’s progress.By default, video starts to playback as soon as 0.1 (one-tenth) seconds of the video has buffered. Larger buffers can ensure a smoother playback. At 0.1 seconds, it is possible that users with slower connections or connections with spikes in network usage could experience choppy playback or frequent rebuffering. If you increase the buffer size, users will most likely experience a smoother playback. You can set the buffer using thebufferTimeproperty; the following sets the buffer time to 10 seconds:videoStream.bufferTime = 10;
Generally a one-buffer-fits-all approach is not the optimal solution. Although it may work in most cases, you cannot ensure the best user experience with that approach. Guaranteeing the best playback experience for all users requires slightly more work. The first step is to detect each user’s bandwidth. Once you’ve detected a user’s bandwidth (see Recipe 16.14), you have two basic options:-
If it’s acceptable that users with slower connections view lower quality encodings of the video, you can encode many versions of the video at different bit rates and select the appropriate one for the user based on the detected bandwidth.
-
If you want all users to view the same video (encoded at the same bit rate), then you can set the buffer based on the detected bandwidth. That means users with slower connections will have much higher buffer values and will have to wait longer before the video starts to playback.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Listening for Cue Points
- InhaltsvorschauYou want to listen for cue points encoded in the FLV.Use an onCuePoint( ) callback.The FLV format allows you to embed cue points within the file. You can use cue points for many purposes, such as:
-
Captions
-
Synchronizing animations with video
-
Logging video playback statistics
You have to embed the cue points in the FLV file using one of the FLV encoders such as the Flash Video Exporter (which ships with Flash Professional), On2 Flix (http:// www.on2.com), or Sorenson Squeeze (http:// www.sorensonmedia.com). When playing back the video, the Flash Player receives a notification when a cue point is reached. As with metadata, cue points don’t use the standard event model used by most of ActionScript 3.0. Rather, when a cue point is reached Flash Player calls a callback method called onCuePoint( ). As with onMetaData( ) the onCuePoint( ) method must be defined for an object that is assigned to the client property of the NetStream object. The onCuePoint( ) method accepts one parameter, which is an object with the following properties:name-
The name assigned to the cue point when encoding.
time-
The time at which the cue point occurs (in seconds)
type-
Either “event” or “navigation,” depending on which type was selected when encoding
parameters-
An associative array with string key/value pairs assigned when encoding the FLV
The following illustrates one way in which you can create a client object, assign theEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Applying Filters to Video
- InhaltsvorschauYou want to apply filter effects (blur, color, displacement map, etc.) to a video.Assign an array of all the filters you want to apply to the Video object’s
filtersproperty.The Video class inherits thefiltersproperty from the DisplayObject class. That means you can apply filters to Video objects just as you would any display object (see Recipe 10.5).Recipe 10.5Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Pausing and Resuming Video
- InhaltsvorschauYou want to pause or resume video playback.Use the pause( ) method of the NetStream class.The pause( ) method of the NetStream class allows you to pause and resume playback of a video. When you call the method without parameters, it toggles the pause state of the video (pauses if it’s playing and resumes if it’s already paused):
videoStream.pause( );
If you pass the method atruevalue, the video pauses if it’s currently playing, and nothing occurs if the video is already paused:videoStream.pause(true);
Likewise, if you call the method with afalsevalue, it resumes if the video is paused, and nothing occurs if the video is already playing:videoStream.pause(false);
Although it’s a common mistake, you should not use the play( ) method to resume playback of a paused video. The play( ) method is only used to load and start the initial playback of a video.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Stopping Video
- InhaltsvorschauYou want to stop a video from playing and downloading.Use the close( ) method of the NetStream class.When you want to stop a video from playing back, use the close( ) method of the NetStream object that controls the video. When you use the pause( ) method, the video simply pauses and starts playing again (typically when a UI button is pressed by the user), but even when paused, the FLV data continues to download. If you want to completely stop a video from downloading, use the close( ) method, as follows:
videoStream.close( );
When you call the close( ) method, Flash Player deletes the FLV data from the player. If you request the video again, it needs to start the download all over again. It is possible, however, that a web browser might cache the FLV, and subsequent requests to the same FLV might retrieve the cached version. In such instances, subsequent requests for the same FLV would be faster to playback. However, if an FLV is cached, it’s possible that a user might see a cached version rather than an updated version. To ensure that the user always sees the latest version of the FLV, append a unique query string to the FLV request URL, as shown in the following example:videoStream.play("video.flv?uniqueIndex=" + (new Date( )).getTime( ));If you don’t want a video to be cached for digital rights purposes, you cannot use progressive download video. In such cases, you need to stream the video by using a technology such as Flash Media Server, which is outside of the scope of this book.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Scrubbing Video
- InhaltsvorschauYou want to scrub the playback of video (move the playhead forward or backward while the video plays).Use a slider controller in conjunction with the seek( ) method.A common way to control video playback is to “scrub” the video using a slider controller. You can implement a scrub controller by building a slider that uses the seek( ) method to control a NetStream object.The following sample code illustrates one way to write such a controller:
package com.oreilly.as3cb.components { import flash.display.Sprite; import flash.net.NetStream; import flash.events.Event; import flash.events.MouseEvent; import flash.geom.Rectangle; public class VideoScrubber extends Sprite { private var _thumb:Sprite; private var _track:Sprite; private var _stream:NetStream; private var _duration:Number; private var _scrubbing:Boolean; public function VideoScrubber(stream:NetStream, duration:Number) { _stream = stream; _duration = duration; _track = new Sprite( ); _track.graphics.lineStyle( ); _track.graphics.drawRect(0, -2.5, 100, 5); addChild(_track); _thumb = new Sprite( ); _thumb.graphics.lineStyle( ); _thumb.graphics.beginFill(0xFFFFFF); _thumb.graphics.drawRect(-5, -5, 10, 10); _thumb.graphics.endFill( ); addChild(_thumb); addEventListener(Event.ENTER_FRAME, onEnterFrame); _thumb.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); _thumb.addEventListener(MouseEvent.MOUSE_UP, onMouseUp); } private function onMouseDown(event:MouseEvent):void { _scrubbing = true; var rectangle:Rectangle = new Rectangle(0, 0, _track.width, 0); _thumb.startDrag(false, rectangle); } private function onMouseUp(event:MouseEvent):void { _scrubbing = false; _thumb.stopDrag( ); } private function onEnterFrame(event:Event):void { if(_duration > 0) { if(_scrubbing) { _stream.seek(_duration * _thumb.x / _track.width); } else { _thumb.x = _stream.time / _duration * _track.width; } } } } }Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Clearing the Video Display
- InhaltsvorschauYou want to clear a video display.Call the clear( ) method of the Video object.When you close a NetStream object, it doesn’t automatically clear the video display. The last frame of the video remains visible in the Video object until you either remove the Video object or call the clear( ) method. The following example clears a Video object by calling the clear( ) method.
video.clear( );
You can remove a Video object from the display list by way of removeChild( ).removeChild(video);
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Determining User Bandwidth
- InhaltsvorschauYou want to optimize a user’s video playback by determining her network bandwidth.Download an image file and time the download to calculate the speed of the user’s network connection.Unfortunately, the Flash Player doesn’t have a built-in bandwidth detection system. And because actual bandwidth varies based on many factors (such as network usage, interference in wireless networks, applications running on the same system competing for bandwidth, etc.), there is no way to accurately predict what a user’s bandwidth will be for the next 10 minutes, hour, or any amount of time. However, you can measure a user’s actual bandwidth over a period of time and use that to determine what her bandwidth could be in the near future.To measure a user’s bandwidth, you need to download a (noncompressed) file, such as a JPEG file using Flash Player. Using ActionScript, you can measure both the total bytes downloaded and the amount of time it took to download those bytes. Using those two values, you can calculate an average amount of data downloaded per unit of time. For the purposes of video, bandwidth is usually measured as bit rate in units of kilobits per second. There are 8 bits in a byte and 1,000 bytes per kilobyte. That means you can use the following to convert from bytes to kilobits:
kilobits = bytes / 1000 * 8;
The ratio of bytes/kilobytes and bits/kilobits is different if you are talking about data communication or disk storage. For disk storage, the ratio is 1/1024, while for data communications it is 1/1000.The larger the file that the user has to download, the more accurate the measurement is likely to be. For example, if the user downloads a 10 kilobyte file, it may be that the request hits a network lag and the measurement can be significantly lower than the actual average bandwidth. On the other hand, you don’t want to force the user to download too large a file, since that would cause the user to have to wait too long while testing bandwidth.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Chapter 17: Storing Persistent Data
- InhaltsvorschauMuch of the data you work with in ActionScript is stored in memory while the movie is executing. When the movie is closed, the memory is released and the data is no longer available. What if you want to be able to store data between different visits to the movie? Or what if you want to be able to share data between movies running on the same client? To accomplish these feats, you’ll need to look at how you can store data outside of the Flash Player.In ActionScript, the SharedObject class lets you to implement persistence on the client machine. There are two types of shared objects that can be created: local and remote. This chapter focuses solely on local shared objects (LSOs).Local shared objects are similar to browser cookies in that they are stored on the client’s machine. LSOs are useful for storing the same kind of information for which cookies have traditionally been used, such as the ability for a web site to remember a user so that the user does not have to manually login during each visit. However, LSOs are more powerful than cookies because, by default, they never expire, they can store more data than cookies, they aren’t transmitted between the client and server, and they can store native ActionScript datatypes. In contrast to remote shared objects (RSOs), LSOs are available to use without any additional software involved on either the client or server.You want to store information that persists between visits to a .swf file.Use a LSO.As mentioned in the introduction to this chapter, LSOs are to Flash what cookies are to web browsers—but more so. They are called “super cookies” by some developers because they allow you to store large amounts of data and store and retrieve many intrinsic ActionScript datatypes (as well as objects created from custom classes). In general, LSOs are referred to asEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- Introduction
- InhaltsvorschauMuch of the data you work with in ActionScript is stored in memory while the movie is executing. When the movie is closed, the memory is released and the data is no longer available. What if you want to be able to store data between different visits to the movie? Or what if you want to be able to share data between movies running on the same client? To accomplish these feats, you’ll need to look at how you can store data outside of the Flash Player.In ActionScript, the SharedObject class lets you to implement persistence on the client machine. There are two types of shared objects that can be created: local and remote. This chapter focuses solely on local shared objects (LSOs).Local shared objects are similar to browser cookies in that they are stored on the client’s machine. LSOs are useful for storing the same kind of information for which cookies have traditionally been used, such as the ability for a web site to remember a user so that the user does not have to manually login during each visit. However, LSOs are more powerful than cookies because, by default, they never expire, they can store more data than cookies, they aren’t transmitted between the client and server, and they can store native ActionScript datatypes. In contrast to remote shared objects (RSOs), LSOs are available to use without any additional software involved on either the client or server.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- Creating and Opening a Local Shared Object
- InhaltsvorschauYou want to store information that persists between visits to a .swf file.Use a LSO.As mentioned in the introduction to this chapter, LSOs are to Flash what cookies are to web browsers—but more so. They are called “super cookies” by some developers because they allow you to store large amounts of data and store and retrieve many intrinsic ActionScript datatypes (as well as objects created from custom classes). In general, LSOs are referred to as Flash cookies.The default maximum size that LSOs can grow to is 100 KB. However, counting on the use of this much storage space for a movie could lead to potential problems because users have full control over the size of LSOs through the Flash Player’s Settings Manager and can restrict growth as they see fit. LSO files are saved to the client computer in a binary file ending with a .sol extension. Flash movies within the same domain can write to and read from the .sol files by means of ActionScript’s flash.net.SharedObject class.When a .sol file is created, it is placed in an application data directory for the Flash Player. For users using Microsoft Windows, it will be in a directory something like this: C:\\Documents and Settings\\[ username ] \\Application Data\\Macromedia\\Flash Player\\#SharedObjects\\ [ random character directory name ]. On Mac OS X, the directory will be something like /Users/[ username ] /Library/Preferences/Macromedia/Flash Player/#SharedObject/ [ random character directory name ]. The random character directory name is essential for security purposes. A rogue .swf movie might try guessing the name and location of a shared object from a particular web site so that it can load the LSO from the filesystem to gain access to data it normally doesn’t have access to. After all,Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- Writing Data to a Shared Object
- InhaltsvorschauYou want to add data to an LSO.Add the values as properties of the shared object’s
dataobject.Shared objects have a special built-in property nameddata. Thedataproperty is an object to which you should add any information that you want stored in the shared object:// Store a username value to the example shared object. example.data.username = "Darron";
Unlike previous versions of ActionScript, properties can no longer be attached directly to the shared object. A compile-time error is generated when trying to store data on the SharedObject instance itself instead of in thedataproperty. This prevents potential erroneous attempts to save data:example.variable = "This will cause a compile-time error.";
Additionally, trying to assign a value to thedataproperty directly is incorrect:example.data = "This will cause another compile-time error.";
The correct approach is to attach the value to a new property under thedataproperty, as follows:example.data.variable = "This is the correct way to store data.";
You can store several native ActionScript datatypes to the shared object’sdataproperty, as follows.example.data.exampleArray = new Array( "a", "b", "c" ); example.data.exampleDate = new Date(); example.data.exampleObject = { key1: "example", key2: -12, key3: null };However, you cannot store visual elements (such as movie clips, sprites, buttons, or text fields) or shared objects themselves to a shared object’sdataproperty so that the data persists correctly between sessions.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Saving a Local Shared Object
- InhaltsvorschauYou want to save data in an LSO to the client computer.Use the SharedObject.flush( ) method.Flash automatically attempts to save LSO data to disk when either the movie is unloaded from the Player (such as when the Player closes), when the SharedObject instance is garbage collected (which occurs when there are no longer any references to the instance) or when the SharedObject.clear( ) method is invoked. However, it isn’t a good practice to rely on the automatic save function, as there are several reasons why the data might not be written to disk successfully. Instead, you should explicitly instruct the LSO to write the data to disk using the SharedObject.flush( ) method:
var flushResult:String = example.flush( );
The flush( ) method takes an optional parameter specifying the minimum amount of disk space, in bytes, that should be used when writing the shared object. The value specified defaults to 0, meaning that only the minimum required space should be used to write the local shared object to disk.When the flush( ) method is invoked, it attempts to write the data to the client computer. The result of a flush( ) invocation can be one of three possibilities:-
If the user denies LSO storage for the domain, or if the Flash Player fails to save the data for some reason, the data is not saved and the method throws an Error.
-
If the amount of disk space required to save the LSO’s data is less than the local storage setting for the domain, the data is written to disk and the method returns SharedObjectFlushStatus.FLUSHED, indicating a successful call. When the optional minimum disk space is passed to flush( ), the amount of space allotted must be greater than or equal to that value for the data to be flushed successfully.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Reading Data from a Shared Object
- InhaltsvorschauYou want to read values that have been previously written to a LSO.Read the values from the properties stored in the shared object’s
dataproperty.There is nothing difficult about reading the values from a client-side shared object. All persistent values are stored in the shared object’sdataproperty, so you simply read the values from thedataproperty, as follows:// Read the value of exampleProperty from the shared object, // example, and display it in the Output window. trace( example.data.exampleProperty );
By using a combination of reading and writing data, you can determine if this is the first time a user is viewing a .swf file.// Create a shared object and store some data in it var example:SharedObject = SharedObject.getLocal( "example" ); if ( example.data.previouslyViewed ) { // The user has already viewed the .swf file before, perhaps // we skip an introductory help screen here. } else { // This is the first time the user is viewing the .swf file // because previouslyViewed has not yet been set to true. // Set previouslyViewed to true so that the next time this // code is run we know the user has been here before. example.data.previouslyViewed = true; example.flush( ); }Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Removing Data from a Shared Object
- InhaltsvorschauYou want to remove properties from a shared object, or you want to remove the entire shared object from the disk.Use delete to delete a property from the shared object’s
dataproperty, or use the clear( ) method to remove the shared object.Removing data from a shared object is a straightforward process, but it has to be done the correct way. In ActionScript you will commonly find that people set complex variables such as objects or arrays tonullorundefinedto remove them. Doing this with a shared object, however, is the wrong approach.// Attempt to delete someVariable from the example shared object. // This statement will compile but does not do as we intend it to. example.data.someVariable = null;
A shared object is capable of storing bothnullandundefinedas valid values. Therefore, the preceding code does not removesomeVariablefrom thedataproperty, but rathersomeVariableis given the value ofnullin the assignment statement instead of being removed from the shared object. The correct way to completely remove something from a shared object is to delete it, like this.// Remove someVariable from the example shared object. delete example.data.someVariable;
You can also remove an entire shared object by invoking the clear( ) method on it. After the clear( ) method is called, the physical .sol file that stores the shared object is removed form the disk. The following code is an example of removing a shared object.// Create a shared object and store some data in it var example:SharedObject = SharedObject.getLocal( "example" ); example.data.someData = "a value"; // Displays: a value trace( example.data.someData ); // Remove the shared object from the disk example.clear( ); // Displays: undefined trace( example.data.someData );
After a shared object has been cleared, the shared object reference is still valid. This means that you can use the shared object as if it were newly created. Adding values to theEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Serializing Custom Classes
- InhaltsvorschauYou want to store an instance of a custom class in an LSO.Use the flash.net.registerClassAlias( ) method to preserve type information and add the class instance to the shared object’s
dataproperty.LSOs use a special binary format, Action Message Format (AMF), for encoding information. When you store a class instance in an LSO, the instance is encoded as a generic object that contains properties. Thus, when you try to read the instance back from the shared object, it cannot be read as a class instance because it was not encoded with type information.To get around this limitation, the registerClassAlias( ) method from the flash.net package is used. This method is very similar to the Object.registerClass( ) method used in ActionScript 1.0 and 2.0; however, Object.registerClass( ) has been removed from ActionScript 3.0 and replaced with flash.net.registerClassAlias( ).The registerClassAlias( ) method takes two parameters. The first parameter is a string alias that is used to represent a class. You can use an arbitrary string value that you want as the alias, but the best practice is to use the fully qualified class name. If you have aPersonclass in amodelpackage, the string alias you should use ismodel.Personto provide clarity and avoid ambiguity. This approach also avoids accidentally using a string alias multiple times, since it is impossible to have two classes with the same fully qualified class name. The second parameter is the reference to the class you want to map the class alias to.registerClassAlias( "somePackage.ExampleClass", ExampleClass );
This code tricks the LSO into storing information about the class that created it. Therefore, when the data is retrieved from the shared object, the Flash Player knows what kind of object it is.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Sharing Data Between Flash Applications
- InhaltsvorschauYou want two movies within the same domain to have access to the same LSO.Specify a local path parameter when creating and opening the LSO.By default, LSOs are saved to a path on the client computer that is unique to the domain, path, and name of the .swf file calling the getLocal( ) method. This prevents name conflicts between LSOs from different domains, or even different movies on the same domain. For example, on a system running Windows XP, if a movie named movie.swf served from http://www.person13.com/ascb writes an LSO named
example, the data is saved in a location such as the following:C:\\Documents and Settings\\[user name]\\Application Data\\Macromedia\\Flash Player\\#SharedObjects\\[random directory name]\\person13.com\\ascb\\movie.swf\\example.sol
The name of the .swf file is included in the path to which the LSO is saved so it won’t conflict with an LSO namedexamplecreated by another movie served from the same domain and path. However, in some cases, you want two movies on the same domain to have access to the same LSO. In these cases, you should use the optional local path parameter when creating and opening the LSO using getLocal( ).The local path parameter (the second parameter passed to getLocal( )) must be a string that specifies the full or partial path to the .swf file that created the LSO; for example:var example:SharedObject = SharedObject.getLocal( "example", "/" );
If the preceding code exists in movie.swf, which is served from http://www.person13.com/ascb, the LSO is stored at a location such as the following:C:\\Documents and Settings\\[user name]\\Application Data\\Macromedia\\Flash Player\\#SharedObjects\\[random directory name]\\person13.com\\example.sol
The difference in this directory versus the one presented earlier is that it lacks the movie and path information. An LSO created this way can be opened by any other Flash movie in the same domain with the following line of ActionScript:Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Controlling the Size of Local Shared Objects
- InhaltsvorschauYou want to control the amount of disk space used by a shared object.Use the Security.showSettings( ) method or visit the web site for the Flash Player Settings Manager.As mentioned in Recipe 17.8, the default size for an LSO is 100 KB. Recipe 17.3 explained that the flush( ) method can be used to request a certain amount of disk space for an LSO. If the disk space requested exceeds the maximum allowed value, the user is prompted to either allow or deny the request. Through the use of the flash.system.Security.showSettings( ) method, it is possible to bring up a dialog that allows the user to set the maximum amount of data allowed to be stored in an LSO. The following code opens the Settings UI to the local disk storage section.
// Show the settings for local storage Security.showSettings( SecurityPanel.LOCAL_STORAGE );
To coincide with the Settings UI for a specific domain, there is a more comprehensive Settings Manager that allows a user to change to global settings. Athough the Settings UI and Settings Manager provide similar functionality, they are completely different items. The Settings UI is a special form inside the Flash Player that is displayed via the showSettings( ) method, allowing the user to control the settings for a specific domain. The Settings UI can be opened through ActionScript as the preceding code block shows. It can also be opened manually by right/Control-clicking inside the Flash Player, and then selecting Settings from the contextual menu. In contrast, the Settings Manager is accessed via the macromedia.com web site. To open the Settings Manager to the Website Storage form, go tohttp://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager07.html.This URL may look like just a simple a web page or screenshot, but it’s actually a functional Flash application that modifies the global settings of the Flash Player. Updating a value via the Settings Manager URL affects how the Flash Player behaves. For instance, if you want to change the default size of an LSO (for LSOs that have not been initially created yet), navigate to the Global Storage Settings page (Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Chapter 18: Communicating with Other Movies
- InhaltsvorschauWhen discussing Flash movies interacting with one another, there are two possible scenarios to consider. First, two movies running on the same client computer may have the ability to communicate with each other. Second, there is communication between movies running on different computers.Prior to Version 6 of the Flash Player, the only way to communicate between movies on the same computer (without using server-side functionality) was to use the fscommand( ) function to execute JavaScript methods and use that JavaScript to bridge the communication gap between the movies. Unfortunately, these methods were both cumbersome to use and not always reliable (due to lack of support in various browsers). Also, these methods worked only with Flash movies running in web browsers in which the browser windows had references to one another. However, Flash Player 6 introduced local connections, a means by which any Flash movie can broadcast to and listen for broadcasts from any other movie on the same computer. The advantages of local connections are:
-
They are relatively simple to use.
-
They are implemented entirely in ActionScript and they work for movies running in Flash Player 6 or later.
To communicate between movies on separate client computers, the use of a server-side technology is required. There are three possible approaches to use in this scenario:-
Remote shared objects can be used in conjunction with Flash Media Server (formerly Flash Communication Server) to allow separate movies to send and receive data between themselves.
-
A socket connection can be made to a server that can handle a message passing between all connected clients.
-
For communication that is not considered real-time, it is possible to use a polling methodology coupled with a server-side technology to send and receive new information from the server at certain intervals.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Introduction
- InhaltsvorschauWhen discussing Flash movies interacting with one another, there are two possible scenarios to consider. First, two movies running on the same client computer may have the ability to communicate with each other. Second, there is communication between movies running on different computers.Prior to Version 6 of the Flash Player, the only way to communicate between movies on the same computer (without using server-side functionality) was to use the fscommand( ) function to execute JavaScript methods and use that JavaScript to bridge the communication gap between the movies. Unfortunately, these methods were both cumbersome to use and not always reliable (due to lack of support in various browsers). Also, these methods worked only with Flash movies running in web browsers in which the browser windows had references to one another. However, Flash Player 6 introduced local connections, a means by which any Flash movie can broadcast to and listen for broadcasts from any other movie on the same computer. The advantages of local connections are:
-
They are relatively simple to use.
-
They are implemented entirely in ActionScript and they work for movies running in Flash Player 6 or later.
To communicate between movies on separate client computers, the use of a server-side technology is required. There are three possible approaches to use in this scenario:-
Remote shared objects can be used in conjunction with Flash Media Server (formerly Flash Communication Server) to allow separate movies to send and receive data between themselves.
-
A socket connection can be made to a server that can handle a message passing between all connected clients.
-
For communication that is not considered real-time, it is possible to use a polling methodology coupled with a server-side technology to send and receive new information from the server at certain intervals.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Creating Local Connections
- InhaltsvorschauYou want to communicate from one or more Flash movie(s) to another Flash movie playing on the same client computer.Use the LocalConnection class in the flash.net package to invoke a function in the receiving movie from the sending movie. Use LocalConnection.connect( ) to listen for messages in the receiving movie and define the function that will be invoked. Use LocalConnection.send( ) from the sending movie(s) to invoke a function in the remote movie. Both the sending and receiving movies must specify the same named channel for communication.When two or more Flash movies are playing on the same client computer, they can communicate with one another via a local connection created with the flash.net.LocalConnection class. As long as the movies are playing on the same computer, a connection can be made regardless of the domains from which the movies are being served.By default, movies accept communications from movies on the same domain only. However, you can configure them to receive from other domains as well. See Recipe 18.4.To successfully communicate between multiple movies on the same computer, you must do three things:
-
Configure the receiving movie to listen for communications.
-
Tell the receiving movie what to do when messages are received.
-
Send messages to the receiving movie from the sending movie(s).
A receiving movie must listen for messages over a specific, named local connection. To establish this communication channel, you should create a local connection object in the receiving movie and tell it to listen to a named connection using the connect( ) method:import flash.net.LocalConnection; // Create the local connection object in the receiving movie. var receiver:LocalConnection = new LocalConnection( ); // Instruct the local connection instance to listen for messages // sent over the "
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Sending Data
- InhaltsvorschauYou want to send data to one or more movies playing on the same computer.Pass the data as additional parameters to the send( ) method of the sending local connection object.You can send data to another movie using a local connection by passing the data as additional parameters to the send( ) method of the sending local connection object. The send( ) method requires at least two parameters: the name of the connection and the name of the method to invoke on the receiving movie. Any additional parameters passed to the send( ) method are automatically passed as parameters to the receiving movie’s method. Note that the name of the method you are invoking on the receiving movie cannot be one of the built-in method or properties of the LocalConnection class, or the send( ) call will fail. The built-in method and property names that cannot be used as the method name parameter are send, connect, close, allowDomain, allowInsecureDomain, client, and domain.You should define the receiving method so it accepts the parameters sent to it. In this example, a local connection receiver class is created that contains a method named example( ). The method expects three parameters:
str,num, andbool; for example:package { import flash.net.LocalConnection; public class ExampleReceiver { private var _receiver:LocalConnection; public function ExampleReceiver( ) { // Instantiate the local connection receiver and listen on the // "_exampleChannel" channel for other movies calling the example // method. _receiver = new LocalConnection( ); _receiver.connect( "_exampleChannel" ); _receiver.client = this; } public function example( str:String, num:Number, bool:Boolean):void { trace( "The parameters are: " + str + "\\n" + num + "\\n" + bool ); } } }The following code snippet sends a message that callsEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Validating Receipt of Communication over Local Connections
- InhaltsvorschauYou want a sending movie to receive confirmation that the communication was successfully received.Configure the receiving movie to return a receipt to the sending movie.To confirm that a communication was received, you can have the receiving movie send a message back to the original sending movie. Due to the nature of local connections, a single channel cannot be used for two-way communication. For this reason, we have to create a local connection channel for each direction of communication. Use the following steps to confirm receipt of a message:
-
Set up the sending and receiving movies, as described in Recipe 18.1.
-
In addition to whatever code you include in the method that is invoked on the receiving movie, write code to send a receipt over a new channel (for example,
"_exampleChannelReceipt"). You can use this.send( ) within the local connection’s method to send a receipt back to the original sender. -
In the sending movie, call the connect( ) method, passing it the name of the channel over which the receiving movie sends the receipt (
"_exampleChannelReceipt"). -
In the sending movie, create a method on the local connection object to handle the receipt communication. Make sure this method name matches the name of the method that the receiving movie invokes when sending the receipt.
The following is an example of some code from a sending movie and a receiving movie.First, the receiving movie code, using the DynamicLocalConnection class:// Create the receiving code to listen on the "_exampleChannel" // channel. var receiver:DynamicLocalConnection = new DynamicLocalConnection( ); receiver.connect( "_exampleChannel" ); receiver.example = function( ):void { // In addition to whatever other code goes in the // receiving method, add this code to issue a receipt // back to the sending movie over the "Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Accepting Local Communications from Other Domains
- InhaltsvorschauYou want a movie to accept local connection communications from movies served from other domains.Use the allowDomain( ) method of the receiving local connection object.By default, receiving movies accept communications from sending movies on the same domain only. However, you can use the allowDomain( ) method of a local connection object to allow or disallow communications from any domain. You need to call the allowDomain( ) method for each receiving local connection object for which you wish to define a custom list of domains to accept or deny.The behavior of allowDomain( ) has changed from previous versions of ActionScript. Before, the method acted as a callback. It would automatically invoke when a local connection object received a communication. Based on the return value of the method, the communication was either accepted or denied.In ActionScript 3.0, the allowDomain( ) method needs to be explicitly called on a LocalConnection instance. The method takes one or more strings, specifying the domains that are allowed to send messages to the local connection instance that allowDomain( ) is called from. In this example, we specifically allow movies from darronschall.com to send messages to the current movie.
var receiver:LocalConnection = new LocalConnection( ); receiver.connect( "_exampleChannel" ); // Allow movies from darronschall.com to send data over // "_exampleChannel" to execute code within this movie. receiver.allowDomain( "darronschall.com" );
To allow more than one domain to be able to send data to a movie, pass additional parameters to the allowDomain( ) method with one string for each domain to allow:receiver.allowDomain( "macromedia.com", "adobe.com", "google.com" );
There are two special domain strings that can be used in allowDomain( )Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Chapter 19: Sending and Loading Data
- InhaltsvorschauThere are many reasons why you may want to send and load values from and to your Flash movies, including to:
-
Send form values to a server-side script to store in a database.
-
Send values from an email form to a server-side script to send the email.
-
Load values from a text file (appropriate when the values are subject to change, such as for the current weather or for a links page).
-
Load values from a server-side script where the values are drawn from a database, such as categories in an e-commerce application.
-
Send values to a server-side script for processing, and return a value to the Flash movie, such as for a login process.
When loading data from a URL, the Flash Player interprets the data in one of three possible ways: as text, raw binary data, or URL-encoded variables. URL-encoded variables follow these rules:-
Each variable name is associated with a value using an equals sign, without spaces on either side of the equals sign.
-
Variable values loaded into Flash movies are always treated as strings; therefore, you should not enclose any values in quotes, as you would within ActionScript. A proper example of this is
artist=Picasso. -
When there is more than one name/value pair, each pair is separated by an ampersand—for example,
artist=Picasso&type=painting. -
Spaces within the values should be replaced by plus signs (
+), not%20, as in:title=The+Old+Guitarist. (Spaces and%20may also work, but stick with plus signs for the greatest compatibility.) -
Any character that is not a digit, a Latin 1 letter (non-accented), or a space should be converted to the hexadecimal escape sequence. For example, the value “L’Atelier” should be encoded as
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Introduction
- InhaltsvorschauThere are many reasons why you may want to send and load values from and to your Flash movies, including to:
-
Send form values to a server-side script to store in a database.
-
Send values from an email form to a server-side script to send the email.
-
Load values from a text file (appropriate when the values are subject to change, such as for the current weather or for a links page).
-
Load values from a server-side script where the values are drawn from a database, such as categories in an e-commerce application.
-
Send values to a server-side script for processing, and return a value to the Flash movie, such as for a login process.
When loading data from a URL, the Flash Player interprets the data in one of three possible ways: as text, raw binary data, or URL-encoded variables. URL-encoded variables follow these rules:-
Each variable name is associated with a value using an equals sign, without spaces on either side of the equals sign.
-
Variable values loaded into Flash movies are always treated as strings; therefore, you should not enclose any values in quotes, as you would within ActionScript. A proper example of this is
artist=Picasso. -
When there is more than one name/value pair, each pair is separated by an ampersand—for example,
artist=Picasso&type=painting. -
Spaces within the values should be replaced by plus signs (
+), not%20, as in:title=The+Old+Guitarist. (Spaces and%20may also work, but stick with plus signs for the greatest compatibility.) -
Any character that is not a digit, a Latin 1 letter (non-accented), or a space should be converted to the hexadecimal escape sequence. For example, the value “L’Atelier” should be encoded as
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Loading Variables from a Text File
- InhaltsvorschauYou want to load variables from an external text file into your Flash movie.Use the URLLoader.load( ) method in conjunction with
DataFormat.VARIABLESas thedataFormatto read URL-encoded data into a Flash movie.You should use the URLLoader.load( ) method whenever you want to load URL-encoded data into your Flash movie from a text file. This technique allows your Flash movie to access values that frequently change without modifying the Flash movie itself.The load( ) method requires a URLRequest instance as a parameter that points to the URL of the text file. The URL can be an absolute or relative address. Additionally, the URLLoader needs to be configured to interpret the text as URL-encoded variables instead of plain text. Setting thedataFormatproperty of the URLLoader instance to theDataFormat.VARIABLESconstant accomplishes this. Here is code to illustrate loading data from a text file:import flash.net.*; // You must first create the URLLoader object. var example:URLLoader = new URLLoader( ); // Configure the instance to interpret data as URL-encoded variables example.dataFormat = DataFormat.VARIABLES; // This example loads values from a text file at an absolute URL. example.load( new URLRequest( "http://www.darronschall.com/example.txt" ) ); // This example loads values from a text file located at a relative // URL, in this case, in the same directory as the .swf file. example.load( new URLRequest( "example.txt" ) );
Here is an example of what the text file might contain:someText=testing&someNumber=123
Once you invoke the load( ) method of a URLLoader instance, the Flash Player attempts to load the values from a URL into thedataproperty of the same URLLoader instance. After the data loads, Flash attempts to decode the values and dispatches acompleteEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Loading Variables from a Server-Side Script
- InhaltsvorschauYou want to load variables into a Flash movie from a server-side script (ColdFusion, Perl, PHP, etc.).Use the URLLoader.load( ) method in conjunction with
DataFormat.VARIABLESas thedataFormatto read URL-encoded data generated by a server-side script into a Flash movie.The ActionScript to load variables from a server-side script is exactly the same as that used to load variables from a text file. When you call the load( ) method, you should pass it the URL of the script from which you want to load the variables, and then handle the results by listening for thecompleteevent as shown in Recipe 19.1.When the values for variables are generated from a database or another resource accessible only to the server, use server-side scripts as the source for variables loaded into the Flash Player. The script that you use must output URL-encoded data only, beginning from the first character. If you are writing a CGI script in Perl, the result is URL-encoded, so you won’t need to make any special adjustments; for example:#!/usr/bin/perl # In a more practical example this value would be retrieved # from a database or other server-side resource. $someText = "test"; # Define the Content-Type header. print "Content-Type: text/plain\\n\\n"; # Output the name-value pair. print "someText=$someText";However, when you use a ColdFusion page to generate variables to load into your movie, you need to take steps to ensure that it outputs URL-encoded data and that the output begins from the first character. Otherwise, extra whitespace characters may precede the output of the URL-encoded data, causing improperly decoded values. Here is what you should do:-
Include the
<cfsetting enablecfoutputonly="yes">tag at the beginning of the document.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Loading a Block of Text (Including HTML and XML)
- InhaltsvorschauYou want to load a block of text, possibly some HTML or XML.Use the URLLoader.load( ) method in conjunction with
DataFormat.TEXTas the dataFormat to read the text from a file or output from a server-side script.ActionScript 3.0 handles loading text differently than ActionScript 1.0 and 2.0. In previous versions, there were two different callback methods that you could define on a LoadVars instance to interpret data loaded from a URL. The onLoad( ) callback method was invoked when URL-encoded data was processed. The onData( ) method fired when the data was finished downloading, but before it was processed (before onLoad( )). By using onData( ) instead of onLoad( ), you were able to access the text that was downloaded before it was processed as URL-encoded data and lost.The flash.net.URLLoader class behaves differently than LoadVars, its predecessor. The URLLoader does not distinguish between data that has finished downloading and data that has been processed and decoded. Rather, there is only acompleteevent broadcast when data finishes download, and thedataFormatproperty determines how the downloaded data is interpreted. Setting thedataFormatproperty toDataFormat.TEXTinstructs the URLLoader instance to interpret the data as plain text. In Recipes 19.1 and 19.2, thedataFormatproperty is set toDataFormat.VARIABLESto interpret the data as URL-encoded variables. By default, a URLLoader instance processes the data downloaded as text.Consider that you want to load the following HTML text from an external file called example.html, and then display it in an HTML-enabled text field:<b>Title:</b> ActionScript 3.0 Cookbook<br /> <b>Authors:</b> Joey Lott, Darron Schall, Keith Peters<br /> <b>Publisher URL:</b> <a href="http://www.oreilly.com">www.oreilly.com</a>
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Checking Load Progress
- InhaltsvorschauYou want to know how much of the data has loaded.Subscribe to the
progressevent of the URLLoader.The URLLoader class has aprogressevent that is dispatched whenever progress is made in downloading data. The Flash Player passes a flash.events.ProgressEvent instance to the event handler, allowing you to inspect thebytesLoadedandbytesTotalproperties of the event. ThebytesLoadedproperty contains the number of bytes that have been received so far. ThebytesTotalproperty contains the total number of bytes in the file being loaded, or zero if the information is unknown.The data is fully loaded when thebytesLoadedproperty of the ProgressEvent is the same as thebytesTotalproperty. However, this is usually not something you check in yourprogressevent handler. Instead, listen for thecompleteevent, which is dispatched when the data is fully loaded. See Recipes 19.1, 19.2, and 19.3 for examples of handling thecompleteevent.To check on the loading progress, use code like the following:package { import flash.display.*; import flash.text.*; import flash.events.* import flash.net.*; public class CheckProgressExample extends Sprite { private var _output:TextField; public function CheckProgressExample( ) { initializeOutput( ); loadData( ); } private function initializeOutput( ):void { _output = new TextField( ); _output.width = stage.stageWidth; _output.height = stage.stageHeight; addChild( _output ); } private function loadData( ):void { var loader:URLLoader = new URLLoader( ); // Listen for the progress event to check download progress loader.addEventListener( ProgressEvent.PROGRESS, handleProgress ); loader.load( new URLRequest( "example.txt" ) ); } private function handleProgress( event:ProgressEvent ):void { // Calculate the percentage by multiplying the loaded-to-total // ratio by 100 var percent:Number = Math.round( event.bytesLoaded / event.bytesTotal * 100 ); _output.text = " Loaded: " + event.bytesLoaded + "\\n" + " Total: " + event.bytesTotal + "\\n" + "Percent: " + percent; } } }Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Accessing Data Being Downloaded
- InhaltsvorschauYou want to access data as it downloads.Use a flash.net.URLStream instance to load binary data that you can read as the data loads into your movie.Recipe 19.4 outlines how to check on the progress of data as it is downloaded. However, due to the nature of the URLLoader class, the data cannot be read until the download is complete. To read data as it arrives, you must use the URLStream class instead.The URLStream class allows you to read data in a binary format as it loads into the Flash Player, similar to using a URLLoader with its
dataFormatproperty set toDataFormat.BINARY. The interface of URLStream is very similar to URLLoader. You use the same events described in Recipe 19.1 to check for loading success and failure in both URLStream and URLLoader. The key difference is how theprogressevent is handled.In the case of URLLoader, theprogressevent is only useful to indicate the amount of data that has been received and perhaps display the percentage loaded somewhere onscreen. In the case of URLStream, theprogressevent allows you to inspect the data by using thebytesAvailableproperty and one of the various read methods, such as readInt( ), readByte( ), readBoolean( ), etc.Using URLStream is an advanced feature and is recommended only if URLLoader is not sufficient and if you have a good understanding of data on a byte level.The following is some example code that uses a URLStream to load a .txt file, accessing the bytes of the file as it downloads into the Flash Player:package { import flash.display.*; import flash.events.* import flash.net.*; public class CheckProgressExample extends Sprite { public function CheckProgressExample( ) { var streamer:URLStream = new URLStream( ); // Listen for the progress event to act on data // as it is received streamer.addEventListener( ProgressEvent.PROGRESS, handleProgress ); streamer.load( new URLRequest( "example.txt" ) ); } private function handleProgress( event:ProgressEvent ):void { // Cast the target of the event as a URLStream var streamer:URLStream = URLStream( event.target ); // Loop over all of the bytes that are available while ( streamer.bytesAvailable > 0 ) { // Read a byte value and output it to the console window trace( "Read byte: " + streamer.readByte( ) ); } } } }Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Sending Data to a Server-Side Script
- InhaltsvorschauYou want to send data from a Flash movie to a server-side script.Create a URLRequest instance that contains the data and pass it to the script with the flash.net.sendToURL( ) method. If you want to open the results of the script in a specific browser window, use the flash.net.navigateToURL( ) method. If you expect a response, use the URLLoader.load( ) method instead, as described in Recipes 3.12 and 19.7.Use the sendToUrl( ) method from the flash.net package to send data to a server-side script if you do not need to process the result. For example, you might want to submit a web form’s data to a server-side script without displaying any result from the server-side processing. However, the sendToURL( ) method does not return any confirmation that the data was received, so it isn’t practical in most cases. Even if you just want to display a static message, such as “Thank you for submitting the form,” you need confirmation that the variables were successfully received on the server. Therefore, if you want confirmation of receipt, use the URLLoader.load( ) method, as described in Recipes 3.12 and 19.7.The URLRequest instance passed to sendToUrl determines what (and how) data is sent to a server-side script. Typically, the
dataproperty of the request is set to a URLVariables instance to send name-value pairs to the server. It can also be set to a flash.util.ByteArray to HTTPPOSTbinary data to a server, ordatacan be set to a String to send text, perhaps an XML-RPC request (see http://www.xmlrpc.com), to a server. The following code snippet shows how to create a URLRequest by using a URLVariables instance to send name-value pairs to a server-side script:function sendData( ):void { // Create a request that sends data to the process.cfmEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Sending Variables and Handling a Returned Result
- InhaltsvorschauYou want to send variables to a server-side script and handle the results of the server-side processing.Use the URLLoader.load( ) method coupled with a URLRequest instance that has its
dataproperty set.You should use the URLLoader.load( ) method when you want to send variables to a server-side script and have the results returned to Flash. An example of such a scenario is a Flash storefront for a product catalog whose data is stored in a database. Typically, items are categorized. When a user selects a category, the Flash movie might send the selected category ID to a server-side script and expect the script to return all the items in the category.The URLLoader.load( ) method sends variables to a server-side script in the same way that the sendToURL( ) and navigateToURL( ) methods do. Thedataset in the URLRequest instance passed to the load( ) method is sent to the script at the specified URL. Handling results is exactly the same as discussed in Recipe 19.2. When thecompleteevent is handled, thedataproperty of the URLLoader that dispatched the event contains the result of the script processing.Here is a complete example that sends data to a script that returns URL-encoded values and places the result in a text field on the screen:package { import flash.display.*; import flash.text.*; import flash.events.* import flash.net.*; public class SendAndLoadExample extends Sprite { private var _output:TextField; public function SendAndLoadExample( ) { initializeOutput( ); sendData( ); } private function initializeOutput( ):void { _output = new TextField(); _output.width = stage.stageWidth; _output.height = stage.stageHeight; addChild( output ); } private function sendData( ):Void { // Create a URLRequest to contain the data to send // toEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Chapter 20: XML
- InhaltsvorschauXML is a structured, text-based way of formatting and describing data. It was originally designed to be to both simple and flexible and has rapidly grown into an industry standard because of its portability, especially for data exchange and interoperability between applications.When working in ActionScript, XML will probably cross your path. Chapter 19 explains how to send and load data in a URL-encoded format. URL-encoding is fine for passing simple data between the Flash Player and server-side scripts, but for complex data or Unicode characters, XML generally works much better because of its structured format. For example, if you want to load data from a text file that represents a simple datatype such as a string, URL-encoded data, such as the following, can be loaded using a URLLoader instance:
myString=a+string+value
However, when you want to load data from an external source and use that data to create an ActionScript object, you are presented with the problem of how to represent that data as a URL-encoded string. You might try something like the following, in which each property value pair is separated by an asterisk (*), and each property is separated from its corresponding value by a vertical pipe (|):myObject=prop0|val0*prop1|val1*prop2|val2
Once the string value is returned formyObject, you could use String.split( ) to recreate the elements that make up the object. Although you can get by with this approach, it is often much easier to represent complex values in XML. For example, the same object can be represented by the following XML snippet:<myObject> <prop0>val0</prop0> <prop1>val1</prop1> <prop2>val2</prop2> </myObject>
XML data offers several advantages over URL-encoded data, including:-
When creating XML manually (for a static XML document) or programmatically (from a ColdFusion script, PHP script, etc.), it is much easier to represent complex data.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Introduction
- InhaltsvorschauXML is a structured, text-based way of formatting and describing data. It was originally designed to be to both simple and flexible and has rapidly grown into an industry standard because of its portability, especially for data exchange and interoperability between applications.When working in ActionScript, XML will probably cross your path. Chapter 19 explains how to send and load data in a URL-encoded format. URL-encoding is fine for passing simple data between the Flash Player and server-side scripts, but for complex data or Unicode characters, XML generally works much better because of its structured format. For example, if you want to load data from a text file that represents a simple datatype such as a string, URL-encoded data, such as the following, can be loaded using a URLLoader instance:
myString=a+string+value
However, when you want to load data from an external source and use that data to create an ActionScript object, you are presented with the problem of how to represent that data as a URL-encoded string. You might try something like the following, in which each property value pair is separated by an asterisk (*), and each property is separated from its corresponding value by a vertical pipe (|):myObject=prop0|val0*prop1|val1*prop2|val2
Once the string value is returned formyObject, you could use String.split( ) to recreate the elements that make up the object. Although you can get by with this approach, it is often much easier to represent complex values in XML. For example, the same object can be represented by the following XML snippet:<myObject> <prop0>val0</prop0> <prop1>val1</prop1> <prop2>val2</prop2> </myObject>
XML data offers several advantages over URL-encoded data, including:-
When creating XML manually (for a static XML document) or programmatically (from a ColdFusion script, PHP script, etc.), it is much easier to represent complex data.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Understanding XML Structure (Reading and Writing XML)
- InhaltsvorschauYou want to understand how to read or write XML.XML is tag-based and hierarchical. If you are familiar with HTML, learning the basics of XML should not be very difficult.Although reading and writing good XML is not a skill that is specific to ActionScript, it is, nonetheless, a skill from which your ActionScript can benefit. If you are not yet familiar with XML, don’t worry. This is going to be painless.XML is a way of representing structured data. This means that you explicitly define the context for the data. For example, without XML you might have a string of data such as:
Jerry,Carolyn,Laura
You can use XML to tell us who these people are:<family> <father>Jerry</father> <mother>Carolyn</mother> <sister>Laura</sister> </family>
Now, as you can see, the XML tells us a lot more about the data. Here are a few other points to notice about XML:-
XML is composed mainly of nodes. A node is a general term that can refer to many parts within the XML. For example,
<family>is a node in the preceding XML snippet; these nodes are called elements. Also, the values Jerry, Carolyn, and Laura are nodes; these nodes are called text nodes. -
Every XML element must have a matching opening and closing tag. The opening tag might look like
<family>, and the closing tag is identical, except that it uses a forward slash to indicate it is closing the element, as in</family>. The opening and closing tags can be combined if the element does not contain any nested nodes. For example,<emptyElement/>is an element that combines the opening and closing tags. Notice that there is a space between the element name,emptyElement, and the forward slash. The space isn’t necessary; it’s just a matter of personal style.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Creating an XML Object
- InhaltsvorschauYou want to create an XML object complete with a tree structure and data.A populated XML object contains data, just as a populated city contains people.Use one of the following to create a populated XML object:
-
Create an XML object and populate it by assigning to it an XML literal.
-
Populate an XML object tree by passing an XML string to the XML constructor.
-
Create an empty XML object and use E4X to populate the XML tree one node at a time.
-
Create a blank object, and load the XML data from an external source.
There are many possibilities for creating a populated XML object in ActionScript. Each technique offers its own advantages, and you should base your decision on the needs of your project.The simplest way to create a populated XML object is create a new XML object and assign an XML literal to it:var example:XML = <abc><a>eh</a><b>bee</b><c>see</c></abc>;
This is an example of E4X in action. Notice that directly inside the code file, an XML packet is used on the right-hand side of an equals sign. If the XML had been contained in quotation marks, this would be interpreted as a string, but ActionScript 3.0 provides native support for XML datatypes. The ActionScript compiler understands that the expression on the right is XML, and it populates theexampleXML instance with the XML packet provided.This first technique is appropriate when you already know the XML structure before you want to create the object. It is even applicable if you want to use dynamic data inside of the XML literal. Place a variable name inside of curly braces ({and}) to use its value inside the XML literal. For example, if you want to create a simple XML object to send a user’s name and score to the server, you would construct the XML literal as follows:Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Adding Elements to an XML Object
- InhaltsvorschauYou want to construct an XML object and add elements to it.Use E4X syntax to create child elements and add them to an XML tree. Additionally, use the insertChildBefore( ) and insertChildAfter( ) methods for more control over how new elements are added.You might want to add elements to an XML object to construct an XML data structure to pass to another application. There are several ways to accomplish this, as discussed in Recipe 20.2.Adding elements to an existing XML object is simple with E4X syntax. Use the dot operator (
.) on the XML instance and add the element much the same way a generic property is added to a regular Object:// Create an XML instance to add elements to var example:XML = <example />; // Create a new XML node named newElement and add it to the // example instance example.newElement = <newElement />; /* Displays: <example> <newElement/> </example> */ trace( example );
In the preceding example, an XML literal is created for an emptynewElementnode. This is then added to theexampleinstance by using the dot operator and assigning anewElementproperty to thenewElementnode. In this situation, the property name and the element name do not need to be the same. However, it would be confusing if they were not. The element name overrides the property name when adding an XML node to an existing XML object.You can also create a new element by creating a property on the XML instance and assigning it a value, as follows:// Create an XML instance to work with var example:XML = <example />; // Create a new property emptyElement and assign it an empty // string value example.emptyElement = ""; /* Displays: <example> <emptyElement/> </example> */ trace( example );The preceding example demonstrates that you can create child elements on an XML object without actually adding XML nodes, like in the first example. Assigning an empty string value to a newEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Adding Text Nodes to an XML Object
- InhaltsvorschauYou want to add text nodes to an XML object.Use E4X syntax to create text nodes and add them to an XML tree. Use the appendChild( ), prependChild( ), insertChildAfter( ), and insertChildBefore( ) methods for more control over how the text nodes are added.Creating text nodes with E4X is, you guessed it, simple. The process is very similar to the method described in Recipe 20.3. As with elements, creating text nodes is just a matter of using the dot operator (
.) to set a property on an XML instance to any value that can be converted to a string. Here is an example:// Create an XML instance to work with var example:XML = <example/>; // Create a text node from a string example.firstname = "Darron"; // Create a text node from a number example.number = 24.9; // Create a text node from a boolean example.boolean = true; // Create a text node from an array example.abc = ["a", undefined, "b", "c", null, 7, false]; /* Displays: <example> <firstname>Darron</firstname> <number>24.9</number> <boolean>true</boolean> <abc>a,,b,c,,7,false</abc> </example> */ trace( example );
This example adds both text and element nodes to theexampleXML instance. The value on the righthand side of the assignment statement is converted into a string and becomes the text node. Then the property name is converted into an element node with the text node as a child, and the entire element node is appended to the XML instance.For more control over where the text nodes are placed inside of element nodes, use either appendChild( ), prependChild( ), insertChildBefore( ), or insertChildAfter( ). These methods allow you to control precisely where the text node is inserted into the XML tree:// Create an XML instance to work with var example:XML = <example/>; // Append a two element node containing a text node child // with value 2 example.appendChild( <two>2</two> ); // Prepend aEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Adding Attributes to an XML Element
- InhaltsvorschauYou want to add attributes to an XML element.Use the
@operator in E4X syntax to assign attributes to element nodes.Use the@operator to assign attributes to an element with E4X; the basic syntax looks like this:elementNode.@attributeName = "value";
Use the dot operator (.) after an element node variable, followed by the@operator. Immediately after the@symbol, specify the name of the attribute, and use a regular assignment statement to give the attribute a value. The value to the right of the equals sign is converted to a string before being assigned:// Create an XML instance to work with var example:XML = <example><someElement/></example>; // Add some attributes to the someElement element node example.someElement.@number = 12.1; example.someElement.@string = "example"; example.someElement.@boolean = true; example.someElement.@array = ["a", null, 7, undefined, "c"]; /* Displays: <example> <someElement number="12.1" string="example" boolean="true" array="a,,7,,c"/> </example> */ trace( example );When using this syntax, the attribute name must be a valid variable name. This means that the attributes must have names consisting of numbers, letters, and underscores, and the first character cannot be a number. However, XML attribute names can sometimes contain other characters that, when used with the@operator, generate compile errors. In these situations, you can use bracket notation to create attributes whose names contain invalid variable name characters. For example:example.someElement.@["bad-variable-name"] = "yes";
You can also use bracket notation to create attributes dynamically, building the attribute name with variable values. For example:example.someElement.@["color" + num] = "red";
Recipe 20.9Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Reading Elements in an XML Tree
- InhaltsvorschauYou want to extract the child elements of an XML object.Use the elements( ) method to return all of the elements as an XMLList and a for each loop to iterate over the list.You’ll often want to “walk” (traverse) an XML tree to extract or examine one or more elements. This is convenient for searching for a given element or processing elements in which you don’t know (or don’t care about) their precise order.E4X provides a convenient elements( ) method that returns all of the element child nodes of an XML object. By using this method inside a for each loop, you can walk through the XML tree:
var menu:XML = <menu> <menuitem label="File"> <menuitem label="New"/> </menuitem> <menuitem label="Help"> <menuitem label="About"/> </menuitem> This is a text node </menu>; for each ( var element:XML in menu.elements( ) ) { /* Displays: File Help */ trace( element.@label ); }The preceding example demonstrates that the elements( ) method only returns the child nodes of an XML object that are of type element (ignoring the other node types like text). It also only returns the immediate children of the XML object. TheNewandAboutmenuitems are not returned by the menu.elements( ) call in the previous code snippet because they are not immediate children of themenuelement. To walk the entire tree, you’ll need to create a recursive function, as follows:var menu:XML = <menu> <menuitem label="File"> <menuitem label="New"/> </menuitem> <menuitem label="Help"> <menuitem label="About"/> </menuitem> This is a text node </menu>; /* Displays: File New Help About */ walk( menu ); // A recursive function that reaches every element in an XML tree function walk( node:XML ):void { // Loop over all of the child elements of the node for each ( var element:XML in node.elements( ) ) { // Output the label attribute trace( element.@label ); // Recursively walk the child element to reach its children walk( element ); } }Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Finding Elements by Name
- InhaltsvorschauYou want to find an element by its node name rather than by its position in the XML hierarchy.Use E4X syntax to “dot down” to a particular element.E4X makes working with XML objects as simple as working with regular objects. For each element node, you access that element in the same way you access the property of an object; for example:
var fruit:XML = <fruit><name>Apple</name></fruit>; // Displays: Apple trace( fruit.name );
As you can see here, to access thenameelement in the XML packet, use the dot operator (.) and referencenamedirectly of thefruitXML instance. For elements nested deeper in the XML tree, use a series of dots and element names to reach the element, as follows:var author:XML = <author><name><firstName>Darron</firstName></name></author>; // Displays: Darron trace( author.name.firstName );
One shortcut to consider for accessing deeply nested element nodes without knowing the path to get to the node is to use the double-dot operator. For example, you can omit the path and extract thefirstNamenode directly, like this:var author:XML = <author><name><firstName>Darron</firstName></name></author>; // Displays: Darron trace( author..firstName );
The double-dot operator works for any level of nesting; it doesn’t matter if the target node is two or ten levels deep.When there are multiple element nodes that share the same name, accessing the element name from an XML instance becomes indexable, much like an Array. Use bracket notation, coupled with an integer, to access a particular element node; for example:var items:XML = <items> <item> <name>Apple</name> <color>red</color> </item> <item> <name>Orange</name> <color>orange</color> </item> </items>; // Displays: Apple trace( items.item[0].name ); // Displays: Orange trace( items.item[1].name );Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Reading Text Nodes and Their Values
- InhaltsvorschauYou want to extract the value from a text node.Use E4X syntax, or, alternatively, use the text( ) method to return an XMLList of text nodes for an element. Then use the toString( ) method to convert the text node’s value to a string, use a conversion function such as int( ) or Number( ) to convert the value to another datatype, or let the Flash Player automatically convert the value to a specific type.Recipe 20.4 looks at text nodes and how to create them in XML objects. This recipe explains how to extract the value from a text node. You can get a reference to the text node in much the same as you reference element nodes, discussed in Recipes 20.6 and 20.7. Once you have a reference to the text node, you can extract its value by using toString( ) or a conversion method on the node. For example, consider the following XML packet:
<book> <title>ActionScript 3.0 Cookbook</title> </book>
The root node of this XML packet is<book>, which contains<title>as its child element. The<title>element, in turn, contains a nested node; a text node with a value ofActionScript 3.0 Cookbook.If this XML packet is assigned to an XML object, you can “dot down” with E4X syntax to get to thetitleelement node by name, and then use the toString( ) method to access the text node child oftitle:var book:XML = <book> <title>ActionScript 3.0 Cookbook</title> </book>; // Use E4X syntax to access the title element, and assign // it to the title variable. var title:String = book.title.toString( ); // Displays: ActionScript 3.0 Cookbook trace( title );In this example, converting thetitleelement node to a String is done by explicitly invoking the toString( ) method. In truth, you can omit the call to toString( ) because the Flash Player does this for us automatically. However, it is generally a good idea to explicitly useEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Reading an Element’s Attributes
- InhaltsvorschauYou want to extract the attributes of an element.Use the attributes( ) method to return a list of attributes for an element. Alternatively, use the
@operator in E4X syntax or attribute( ) method to access an attribute by name.You should use the attributes( ) method to return an XMLList of attributes for a particular element node. The XMLList returned is indexable, just like an Array instance. Examining a particular index returns the value for the attribute at that index:var fruit:XML = <fruit name="Apple" color="red" />; // Use the attributes( ) method and save the results as an XMLList var attributes:XMLList = fruit.attributes( ); // Displays: Apple trace( attributes[0] ); // Displays: red trace( attributes[1] );
In this example, only the values of the attributes are retrieved. Use the name( ) method on the attribute reference to retrieve itsname. In the following example, the second attribute (located at index 1) is examined for its name:var fruit:XML = <fruit name="Apple" color="red" />; // Displays: color trace( fruit.attributes( )[1].name( ) );
To loop over all of the attributes of an element, use a for each loop. Use a combination of the name( ) method to retrieve the attribute’s name and the attribute reference itself for its value. In the following example, toString( ) is explicitly called on the attribute reference to convert its value to a string, like in Recipe 20.8:var fruit:XML = <fruit name="Apple" color="red" />; for each ( var attribute:XML in fruit.attributes( ) ) { /* Displays: name = Apple color = red */ trace( attribute.name( ) + " = " + attribute.toString( ) ); }If you are interested in a particular attribute and know its name, the E4X syntax makes accessing the element trivial. Use E4X to dot down to the particular element node, and then use theEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Removing Elements, Text Nodes, and Attributes
- InhaltsvorschauYou want to remove an element node, text node, or attribute from an XML object.Use the
deletekeyword.In previous recipes you have learned how to add element and text nodes, and attributes to XML objects. You’ve also learned how to read them back in and loop over them. But what if you want to delete a particular element or attribute? The secret is to use thedeletekeyword, followed by what you want to delete:var example:XML = <example> <fruit color="Red">Apple</fruit> <vegetable color="Green">Broccoli</vegetable> <dairy color="White">Milk</dairy> </example>; // Remove the color attribute from the fruit element delete example.fruit.@color; // Remove the dairy element entirely delete example.dairy; // Remove the text node from the vegetable element node delete example.vegetable.text( )[0]; /* Displays: <example> <fruit>Apple</fruit> <vegetable color="Green"/> </example> */ trace( example );Of particular interest in the preceding example is how the text node was deleted. Using certain methods like text( ) and elements( ) on an XML object, or, in certain situations, using E4X syntax, returns an XMLList with multiple items. Thedeletekeyword only works in conjunction with a single item, and as such, you must use bracket notation to reference a particular item in the XMLList that you want to delete. To delete all the items in the XMLList, use a for loop and iterate over the items in reverse order:var example:XML = <example> <fruit color="red" name="Apple" /> </example>; // Get an XMLList of the attributes for fruit var attributes:XMLList = example.fruit.@*; // Loop over the items backwards to delete every attribute. // By removing items from the end of the array we avoid problems // with the array indices changing while trying to loop over them. for ( var i:int = attributes.length( ) - 1; i >= 0; i-- ) { delete attributes[i]; } /* Displays: <example> <fruit/> </example> */ trace( example );Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Loading XML
- InhaltsvorschauYou want to load XML data from an XML document or a server-side script that generates XML.Use the URLLoader.load( ) method with its
dataFormatproperty set toDataFormat.TEXTto load the data as plain text. Use an event handler for thecompleteevent and convert the text into an XML instance.In previous versions of ActionScript, loading an XML file was done by invoking the load( ) method directly on an XML object. In ActionScript 3.0, sending and loading of data has been consolidated into the new URLLoader class and its related classes. There are no special considerations given to loading XML in ActionScript 3.0, leaving it up to you to implement your own solution.The process of loading an XML file, while multistep, is relatively painless. First, a URLLoader instance must be made to load the data from the URL. To instruct the URLLoader to load the data as plain text, itsdataFormatproperty must be set toDataFormat.Text. An event listener for thecompleteevent needs to be added so you receive notification when the data has finished downloading. In thecompleteevent handler, one of the techniques outlined in Recipe 20.2 should be used to convert the loaded data into an XML object. Finally, the URLLoader.load( ) method must be invoked to kick off the loading process, being passed a URLRequest instance that points to the URL of the XML file. A complete example looks like this:package { import flash.display.*; import flash.events.*; import flash.net.*; import flash.utils.*; public class LoadXMLExample extends Sprite { public function LoadXMLExample( ) { var loader:URLLoader = new URLLoader( ); loader.dataFormat = DataFormat.TEXT; loader.addEventListener( Event.COMPLETE, handleComplete ); loader.load( new URLRequest( "example.xml" ) ); } private function handleComplete( event:Event ):void { try { // Convert the downlaoded text into an XML instance var example:XML = new XML( event.target.data ); // At this point,Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Loading XML from Different Domains
- InhaltsvorschauYou want to be able to load XML from domains other than the domain that the .swf is served from.Use a crossdomain.xml policy file on the remote domain with an entry to allow access from the domain the .swf is served from.See Recipe 3.12 for information about using a crossdomain.xml policy file.Recipe 3.12Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- Sending XML
- InhaltsvorschauYou want to send XML data to a server-side script.Create a URLRequest instance containing the XML data to send. Use flash.net.sendToURL( ) to send the data and ignore the server response, use flash.net.navigateToURL( ) to send the data and open the server response in a specific browser window, or use URLLoader.load( ) to both send the data and download the response into the .swf file.XML is normally used to transfer data to and from applications, and in this case, Flash movies. Therefore, it is quite unusual that you would want to create XML objects in your Flash movies for use within Flash alone. Instead, you generally load XML data from another source, create XML data in Flash for the purpose of sending to another application, or both.This recipe examines sending XML data from Flash to another application, and there are lots of reasons to do this. For example, in a Flash game you might want to use XML to send the user’s name and score to the server. At other times, you might want to send XML packets to a server-side script to invoke server-side functionality. This is a process that is sometimes called a remote procedure call (RPC), and it can use XML to send the function invocation information (function name, parameters, etc.) to the server. There is a formal specification for using XML in this manner called XML-RPC (see http://www.xmlrpc.com). So, as you can see, the possibilities for sending XML to the server are quite diverse.As discussed in Recipe 20.11 and Chapter 19, ActionScript 3.0 consolidates sending and loading data into the methods of the flash.net package. Previously, the XML class contained both send( ) and sendAndLoad( ) methods to send XML to a server, but in ActionScript 3.0 you must use URLRequest instead. Recipes 19.6 and 19.7 cover the basic techniques using aEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- Searching XML
- InhaltsvorschauYou want to search an XML object for nodes or attributes that meet certain criteria.Use the E4X syntax along with predicate filtering on an XML object to pick out certain values from an XML tree.This chapter examines how E4X syntax with XML objects simplifies reading and writing values in an XML tree. As simple as E4X is to use, it is also extremely powerful. E4X syntax is similar to using XPath for searching XML documents. If you are familiar with XPath concepts, using the advanced features of E4X (such as its predicate filtering) should come naturally. Predicate filtering allows you to pick out element nodes that meet a certain Boolean expression condition using the syntax
.(condition), as you’ll see later in this recipe.Let’s start by creating an XML object from an XML literal:var foodgroup:XML = <foodgroup> <fruits> <fruit color="red">Apple</fruit> <fruit color="orange">Orange</fruit> <fruit color="green">Pear</fruit> <fruit color="red">Watermelon</fruit> <servings>3</servings> </fruits> <vegetables> <vegetable color="red">Tomato</vegetable> <vegetable color="brown">Potato</vegetable> <vegetable color="green">Broccoli</vegetable> <servings>2</servings> </vegetables> </foodgroup>;When you know the name of element nodes, you simply dot down to reach them. For example, to return a list of all of the<fruit>element nodes, use the following E4X expression:var fruitList:XMLList = foodgroup.fruits.fruit;
If you’re interested in a particular<fruit>element node, you can access the node by specifying an index value using bracket notation:Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Using HTML and Special Characters in XML
- InhaltsvorschauYou want to use HTML or other text that uses characters with specific meaning in the context of XML.Use a
CDATAtag to enclose the text.While this recipe doesn’t deal with anything specific to ActionScript per se, it is relevant in that it addresses something you’ll likely encounter when working with XML with respect to Flash or otherwise. In XML, certain characters are interpreted in specific ways. For example, the greater-than and less-than characters are interpreted as the delimiters of XML tags. If you try to use one of those characters as part of some group of text within the XML document, it causes parser errors when you try to use the document; for example:<example>a < b</example>
As you can see, the preceding encloses the texta < bin a text node. However, because the less-than character is interpreted in a specific way in the context of an XML document, the example causes a parser error. Another common example is one in which you want to store some HTML within an XML document; for example:<htmlExample><a href="http://www.darronschall.com">Darron</a></htmlExample>
In such a case the HTML is interpreted as XML, not as a string. The preceding XML packet contains<htmlExample>as the root node, with a child<a>node that contains a text node with the string value ofDarron.In any case, you can enclose text in aCDATA(Character Data) tag, which won’t be interpreted by the XML parser. Instead, the parser simply treats the enclosed data as a string.ACDATAtag begins with<![CDATA[and it ends with]]>. Therefore, the first example can be written as follows:<example><![CDATA[a < b]]></example>
The second example can be rewritten as follows:<htmlExample><![CDATA[<a href="http://www.darronschall.com">Darron</a>]]></htmlExample>
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Chapter 21: Web Services and Flash Remoting
- InhaltsvorschauRemote procedure calls (RPCs) are a powerful way to build distributed and robust applications. RPC is essential for most Flash platform applications. For example, you can use RPC to send data to the server from Flash Player or retrieve data from the server to display to the user. There are many ways for making remote procedure calls from Flash Player; however, there are two ways that stand out: web services and Flash Remoting.When referring to web services in this book, the focus is on Simple Object Access Protocol (SOAP). Web services of this type use SOAP for communication between the server and client. SOAP can serialize complex datatypes, which means you can call server-side methods from a client and pass it parameters of both simple (numbers, strings, and Boolean values) and complex types (objects.) The server-side method can even return complex data to the client, such as arrays, Date objects, and even custom datatypes. SOAP web services are supported by nearly every platform, including Java, ColdFusion, PHP, .NET, and Perl to name a few. Flash Player, however, does not have built-in web services support, and it doesn’t natively understand SOAP either.However, Flash Player can communicate over HTTP, and it can parse XML data. Since SOAP web services communicate over HTTP and SOAP is an XML-based protocol, it is possible to use ActionScript to call web services methods.Flash Remoting is very similar to web services, but with a few significant advantages:
-
Flash Remoting uses HTTP as well, but rather than using SOAP, it uses a binary protocol called Active Messaging Format (AMF). Since AMF packets are binary, you can send much more data across the wire at much less expense. The result is that Flash Remoting is faster than other web services.
-
Flash Remoting is natively supported by Flash Player.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Introduction
- InhaltsvorschauRemote procedure calls (RPCs) are a powerful way to build distributed and robust applications. RPC is essential for most Flash platform applications. For example, you can use RPC to send data to the server from Flash Player or retrieve data from the server to display to the user. There are many ways for making remote procedure calls from Flash Player; however, there are two ways that stand out: web services and Flash Remoting.When referring to web services in this book, the focus is on Simple Object Access Protocol (SOAP). Web services of this type use SOAP for communication between the server and client. SOAP can serialize complex datatypes, which means you can call server-side methods from a client and pass it parameters of both simple (numbers, strings, and Boolean values) and complex types (objects.) The server-side method can even return complex data to the client, such as arrays, Date objects, and even custom datatypes. SOAP web services are supported by nearly every platform, including Java, ColdFusion, PHP, .NET, and Perl to name a few. Flash Player, however, does not have built-in web services support, and it doesn’t natively understand SOAP either.However, Flash Player can communicate over HTTP, and it can parse XML data. Since SOAP web services communicate over HTTP and SOAP is an XML-based protocol, it is possible to use ActionScript to call web services methods.Flash Remoting is very similar to web services, but with a few significant advantages:
-
Flash Remoting uses HTTP as well, but rather than using SOAP, it uses a binary protocol called Active Messaging Format (AMF). Since AMF packets are binary, you can send much more data across the wire at much less expense. The result is that Flash Remoting is faster than other web services.
-
Flash Remoting is natively supported by Flash Player.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Calling Web Services Methods
- InhaltsvorschauYou want to call a web service method.Use an mx.rpc.soap.WebService object, and call the method from the WebService object.As mentioned earlier, Flash Player has no built-in web services capabilities, but the Flex framework does include a solution. This recipe discusses how to use the Flex 2 solution for working with web services. For a Flash solution, see additional notes at http://www.rightactionscript.com/ascb.The Flex framework includes mx.rpc.soap.WebService, a class that simplifies calling web services methods by using ActionScript. The first step is to construct a new WebService object, as follows:
var webService:WebService = new WebService( );
Every web service must have a Web Service Description Language (WSDL) resource that describes the service. You can tell the WebService object where to locate the WSDL using thewsdlproperty:webService.wsdl = "http://www.rightactionscript.com/webservices/FlashSurvey.php?wsdl";
Before you can call methods, you must load the WSDL data from the specified URL by using the loadWSDL( ) method:webService.loadWSDL( );
The loadWSDL( ) method makes a request for the WSDL data asynchronously. That means you have to listen for an event to know when the WSDL data has loaded. When the data has loaded, the WebService object dispatches a load event of type mx.rpc.soap.LoadEvent, as shown here:webService.addEventListener(LoadEvent.LOAD, onWSDL);
Once the WSDL data has correctly loaded, call the web services methods directly from the WebService object. For example, the WSDL URL used in this example points to a real web service, which has a method called getAverages( ) that can be called from the WebService object, as follows:webService.getAverages( );
If the method happens to expect parameters, pass them to the method as you would any normal ActionScript method. For example, the same web service also has a method calledEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Handling Web Services Responses
- InhaltsvorschauYou want to retrieve the return value from a web services method.Add a
resultevent listener to the web services method object.Web services methods are complex objects of type mx.rpc.soap.Operation, to which you can assign event listeners. When a web services method returns a value, the method object dispatches a result event of type mx.rpc.events.ResultEvent. If you want to handle the event, you can add a listener to the method object. For example, ifwebServiceis a WebService object that maps to a web service that defines a method called getAverages( ), you can add a listener as follows:webService.getAverages.addEventListener(ResultEvent.RESULT, onGetAverages);
You then call the method normally:webService.getAverages( );
When the listener is called, it is passed a ResultEvent parameter. The ResultEvent class defines a property calledresultthat contains thereturnvalue. Assuming the getAverages( ) web services method returns an associative array with two properties calledflashandactionscript, the following displays those values in a text area calledtextArea:private function onGetAverages(event:ResultEvent):void { textArea.text = "The averages for Flash and ActionScript are " + event.result.flash + " and " + event.result.actionscript; }Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Handling Web Services Errors
- InhaltsvorschauYou want to handle errors from a web service.Listen for a
faultevent.When a web services error occurs, the operation dispatches afaultevent of type mx.rpc.events.FaultEvent. You can add a listener to the Operation object directly. However, it’s generally advisable to handle fault events at the WebService object level. Operation fault events bubble up to the WebService object if they aren’t handled at the Operation level. The following adds a fault event listener to a WebService object:webService.addEventListener(FaultEvent.FAULT, onWebServiceFault);
The FaultEvent class defines a fault property of type mx.rpc.Fault. Fault objects return details about the error using thefaultCode,faultDetail,faultString, androotCauseproperties. The following displays an Alert when an error occurs:private onWebServiceFault(event:FaultEvent):void { var fault:Fault = FaultEvent.fault; var message:String = "An error occurred. The details are as follows\\ncode: " + fault.faultCode; message += "\\ndetail: " + faul.faultDetail; Alert.show("Web Service Error", message); }Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Calling Flash Remoting Methods
- InhaltsvorschauYou want to call a Flash Remoting method.Use a NetConnection object, connect to the Flash Remoting gateway and use the call( ) method to call the method.Flex and Flash have ActionScript-based APIs that are designed to simplify Flash Remoting method calls. However, this recipe discusses the low-level solution that relies only on the intrinsic (native to Flash Player) solution.All Flash Remoting operations rely on the flash.net.NetConnection class. The first step when making Flash Remoting method calls is to construct a new NetConnection object. You should use one NetConnection object per Flash Remoting service (a service generally being a class):
var connection:NetConnection = new NetConnection( );
Next, call the connect( ) method, passing it the URL to the Flash Remoting gateway. For example, if you are using ColdFusion running locally as a standalone product, then try the following:connection.connect("http://localhost:8500/flashservices/gateway/");The following connects to a working example AMFPHP Flash Remoting gateway:connection.connect("http://www.rightactionscript.com/flashremoting/gateway.php");If you don’t know which gateway URL to use, consult either the documentation for the Flash Remoting server product or your network administrator responsible for managing the server portion of Flash Remoting.The connect( ) method does not immediately attempt to connect to the gateway URL. If the URL is invalid, or if there is a server-side error, you won’t receive an error until you actually call a method.The next step is to call a Flash Remoting method using the call( ) method of the NetConnection object. The call( ) method requires two parameters. The first parameter specifies the name and path of the service and method. The second parameter tells theEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Handling Flash Remoting Responses
- InhaltsvorschauYou want to retrieve a
returnvalue from a Flash Remoting method.Use a Responder object with call( ).Recipe 21.1 discusses how to use the call( ) method of a NetConnection object to call a Flash Remoting method. The second parameter of that method is designed for specifying how Flash Player should handle responses. If you pass a value ofnull(as in the examples in that recipe), then no responses are handled. If you want to handle the responses, use a flash.net.Responder object.The Responder constructor lets you pass it two function references, which handlereturnvalues and errors:var responder:Responder = new Responder(onResult, onError);
When the result function gets called, it’s passed one parameter with the value returned by the Flash Remoting method:private function onResult(returnValue:Datatype):void { }The error handler method is passed an object with properties that describe the error in greater detail.The following example makes a call to a Flash Remoting method called getAverages( ) and uses trace( ) to display the values. The getAverages( ) method returns an associative array with two properties calledflashandactionscript:package { import flash.net.NetConnection; import flash.net.Responder; public class Example { private var _connection:NetConnection; public function Example( ) { _connection = new NetConnection( ); _connection.connect("http://www.rightactionscript.com/flashremoting/ gateway.php"); var responder:Responder = new Responder(onResult, onError); _connection.call("FlashSurvey.getAverages", responder); } private function onResult(result:Object):void { trace(result.flash + " " + result.actionscript); } private function onError(error:Object):void { trace(error.description); } } }Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Chapter 22: Building Integrated Applications
- InhaltsvorschauThe ExternalInterface class allows the Flash Player to communicate in a synchronous manner with the application within which it is embedded. In many cases that host application is a web browser. As such, this chapter focuses exclusively on how to build applications that integrate ActionScript and JavaScript when Flash Player is embedded in a browser.You want to call a JavaScript function from ActionScript.Use ExternalInterface.call( ).Use the ExternalInterface.call( ) method to make synchronous calls to JavaScript functions from ActionScript. The call( ) method requires at least one parameter as a string specifying the name of the function to call:
ExternalInterface.call("changeTitle");The function must be defined in the HTML page with the same name:<script language="JavaScript"> function changeTitle(title) { if(title == undefined) { title = "New Title"; } window.title = title; } </script>If the JavaScript function accepts parameters, you can pass values to it by adding additional parameters when calling the call( ) method. For example, the following passes a value to the changeTitle( ) function:ExternalInterface.call("changeTitle", "ActionScript 3.0 Cookbook");Since call( ) is synchronous, any values returned by the JavaScript function are immediately returned to ActionScript. That means you can assign thereturnvalue from a call to a variable. The following ActionScript illustrates how that can work:var title:String = ExternalInterface.call("getTitle");The JavaScript function for the preceding ActionScript call might look like:<script language="JavaScript"> function getTitle( ) { return window.title; } </script>Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Introduction
- InhaltsvorschauThe ExternalInterface class allows the Flash Player to communicate in a synchronous manner with the application within which it is embedded. In many cases that host application is a web browser. As such, this chapter focuses exclusively on how to build applications that integrate ActionScript and JavaScript when Flash Player is embedded in a browser.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- Calling JavaScript Functions
- InhaltsvorschauYou want to call a JavaScript function from ActionScript.Use ExternalInterface.call( ).Use the ExternalInterface.call( ) method to make synchronous calls to JavaScript functions from ActionScript. The call( ) method requires at least one parameter as a string specifying the name of the function to call:
ExternalInterface.call("changeTitle");The function must be defined in the HTML page with the same name:<script language="JavaScript"> function changeTitle(title) { if(title == undefined) { title = "New Title"; } window.title = title; } </script>If the JavaScript function accepts parameters, you can pass values to it by adding additional parameters when calling the call( ) method. For example, the following passes a value to the changeTitle( ) function:ExternalInterface.call("changeTitle", "ActionScript 3.0 Cookbook");Since call( ) is synchronous, any values returned by the JavaScript function are immediately returned to ActionScript. That means you can assign thereturnvalue from a call to a variable. The following ActionScript illustrates how that can work:var title:String = ExternalInterface.call("getTitle");The JavaScript function for the preceding ActionScript call might look like:<script language="JavaScript"> function getTitle( ) { return window.title; } </script>ExternalInterface works for the following browsers:-
Internet Explorer 5.0+ (Windows)
-
Netscape 8.0+ (Windows and Mac OS X)
-
Mozilla 1.7.5+ (Windows and Mac OS X)
-
Firefox 1.0+ (Windows and Mac OS X)
-
Safari 1.3+ (Mac OS X)
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Calling ActionScript Functions
- InhaltsvorschauYou want to call an ActionScript function from JavaScript.Use ExternalInterface.addCallback( ) to register the ActionScript function, and then call the function from the JavaScript reference to the Flash Player object.The ExternalInterface API allows you to register ActionScript functions, which makes them accessible to JavaScript. Use the static addCallback( ) method to register the ActionScript functions. The addCallback( ) method requires two parameters: the name by which you want to be able to reference the function from JavaScript and a reference to the function. The following example registers a function called
displayMessageusing an identifier (the name by which the function can be called from JavaScript) ofshowMessage:ExternalInterface.addCallback("showMessage", displayMessage);From JavaScript, you need to get a reference to the Flash Player object. There are two basic Flash Player versions that run in the browser: ActiveX and the plug-in version. The ActiveX version runs natively in Internet Explorer, while the plug-in version is used by the rest of the browsers.The ActiveX player is controlled by the<object>tag in an HTML page, and you can retrieve a JavaScript reference usingwindow.objectId where objectId is the value of theidattribute of the<object>tag. For example, if the<object>tag’sidattribute isexample, then the reference to the ActiveX player would bewindow.example.The plug-in player is controlled by the<embed>tag in an HTML page, and you can retrieve a JavaScript reference by usingwindow.document.embedName, where embedName is the value of thenameattribute of the<embed>tag. For example, if the<embed>tag’snameattribute isexample, then the reference to the plug-in player would bewindow.document.exampleEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Passing Parameters from HTML
- InhaltsvorschauYou want to pass parameters from HTML to an SWF.Use
FlashVars.FlashVarsprovides a solution by which you can pass parameters to an SWF from HTML. This can be very useful when you want to pass simple data to an SWF and the data is likely to change, depending on where the application is deployed. For example, you might want to pass web services URLs to an SWF when the URLs change, depending on the server on which the SWF is deployed. That enables you to redeploy the SWF with new values without having to recompile the SWF.TheFlashVarssolution requires two parts: one part is implemented in HTML, and the other is implemented in ActionScript.The HTML portion of theFlashVarssolution requires adding a<paramname="FlashVars"> tag to the<object>tag, and aFlashVarsattribute to the<embed>tag. The value for the tag and attribute is a URL-encoded sequence of name-value pairs. For example, the following constitutes a validFlashVarsvalue that defines two name-value pairs,url1andurl2:url1=http://www.example.com&url2=http://www.sample.com
Within ActionScript, you can reference the variables and values passed viaFlashVarsusing theroot.loaderInfo.parametersproperty of any display object. Theroot.loaderInfo.parametersproperty is an associative array, the keys of which are the names of the variables passed to the SWF viaFlashVars. For example, using the preceding example value, theroot.loaderInfo.parametersproperty would have two keys:url1andurl2.UsingFlashVarswith JavaScript, you can pass a query string from the HTML page to an SWF. The following JavaScript illustrates how to write the<object>and<embed>tags with JavaScript so they pass the query string data from the HTML page to the SWF usingFlashVars:Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Chapter 23: File Management
- InhaltsvorschauPrior to Version 8, the Flash Player did not support any mechanism for allowing the user to browse her computer for files. Furthermore, Flash Player didn’t have a mechanism for uploading or downloading files, either. As such, most web applications used HTML-based solutions for uploading and downloading files. Flash-based applications not deployed on the Web often had to use customized solutions for uploading and downloading files. Flash Player 8 and higher now supports the new APIs, which greatly simplify file I/O by allowing Flash Player to browse a user’s system for files to upload and download.Flash Player allows users to browse to files on their local disks and upload and download files using the FileReference and FileReferenceList classes. This chapter discusses the details of working with those APIs.You want to let users download files to their computer.Use the download( ) method of a FileReference object.The flash.net.FileReference class defines a download( ) method that allows users to download a file from a URL to their computers. When Flash Player calls the download( ) method, it attempts to open a dialog box, titled “Select location for download.” This dialog box allows users to use a standard operating system dialog to browse their local disks for a location to which they want to save files.The first step before calling the download( ) method is to construct a FileReference object, as follows:
var fileReference:FileReference = new FileReference( );
The download( ) method requires at least one parameter as a URLRequest object, specifying the URL from which you want to download the file. In the simplest case, the URL points to a static file that the user can download. The following example opens a save dialog box that allows users to select a location to which they can save a copy ofEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Introduction
- InhaltsvorschauPrior to Version 8, the Flash Player did not support any mechanism for allowing the user to browse her computer for files. Furthermore, Flash Player didn’t have a mechanism for uploading or downloading files, either. As such, most web applications used HTML-based solutions for uploading and downloading files. Flash-based applications not deployed on the Web often had to use customized solutions for uploading and downloading files. Flash Player 8 and higher now supports the new APIs, which greatly simplify file I/O by allowing Flash Player to browse a user’s system for files to upload and download.Flash Player allows users to browse to files on their local disks and upload and download files using the FileReference and FileReferenceList classes. This chapter discusses the details of working with those APIs.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- Downloading Files
- InhaltsvorschauYou want to let users download files to their computer.Use the download( ) method of a FileReference object.The flash.net.FileReference class defines a download( ) method that allows users to download a file from a URL to their computers. When Flash Player calls the download( ) method, it attempts to open a dialog box, titled “Select location for download.” This dialog box allows users to use a standard operating system dialog to browse their local disks for a location to which they want to save files.The first step before calling the download( ) method is to construct a FileReference object, as follows:
var fileReference:FileReference = new FileReference( );
The download( ) method requires at least one parameter as a URLRequest object, specifying the URL from which you want to download the file. In the simplest case, the URL points to a static file that the user can download. The following example opens a save dialog box that allows users to select a location to which they can save a copy of example.txt from the same directory on the server where the SWF resides:var urlRequest:URLRequest = new URLRequest("example.txt"); fileReference.download(urlRequest);Specifying a full path to a file is as simple as specifying the URL when constructing the URLRequest object, as the following example illustrates:var urlRequest:URLRequest = new URLRequest("http://www.myexamplesite.com/example.txt"); fileReference.download(urlRequest);The save dialog box also allows users to change the name of the file they’re downloading. By default, the filename field displays the name of the file as it exists on the server. In the preceding example, the filename field in the save dialog box displays example.txt. In many cases, though, you may want to use a different default name than the name of the file specified in the URL. For example, if a static file was created by a server-side script, it may have a unique identifier name as its filename (e.g.,Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Detecting When a User Selects a File to Upload
- InhaltsvorschauYou want to detect when a user selects a file in order to start a download.Listen for the
selectevent. Listen for thecancelevent to detect when the user has clicked the cancel button.The download( ) method does not pause the execution of ActionScript code. As soon as the download( ) method is called, Flash Player attempts to open the save dialog box. Once it either successfully opens the save dialog box or throws an error, the Flash Player continues to the next line of ActionScript code. That means you cannot expect the user to have selected a file and clicked the Save button immediately following the download( ) method call. Rather, you must listen for aselectevent to tell you when the user has pressed the Save button. Theselectevent is of type Event, and you can use theEvent.SELECTconstant to add the listener, as follows:fileReference.addEventListener(Event.SELECT, onSelectFile);
As soon as theselectevent occurs, you can retrieve the filename the user has selected by reading thenameproperty of the FileReference object:private function onSelectFile(event:Event):void { trace(event.target.name); }The user also has the option of clicking the Cancel button from the save dialog box. If the user clicks the Cancel button, the file is not downloaded, and the dialog closes. When the user clicks the Cancel button, the FileReference object dispatches acancelevent of type Event. You can use theEvent.CANCELconstant to add a listener, as follows:fileReference.addEventListener(Event.CANCEL, onCancelDialog);
Recipe 23.1Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Monitoring Download Progress
- InhaltsvorschauYou want to monitor download progress.Listen for the
progressevent.You can monitor the progress of a file(s) as it downloads by using theprogressevent. Every time part of the file downloads to the user’s computer, the FileReference object dispatches aprogressevent of type ProgressEvent. You can use theProgressEvent.PROGRESSconstant to add a listener, as follows:fileReference.addEventListener(ProgressEvent.PROGRESS, onFileProgress);
Theprogressevent object has two properties,bytesLoadedandbytesTotal, which return the bytes that have downloaded and the total bytes, respectively. The following example method uses the values of those properties to display the download progress in a text field calledfileProgressField:private function onFileProgress(event:ProgressEvent):void { fileProgressField.text = event.bytesLoaded + " of " + event.bytesTotal + " bytes"; }When the file has completed downloading, the FileReference object dispatches a complete event of type Event. Use theEvent.COMPLETEconstant to add a listener:fileReference.addEventListener(Event.COMPLETE, onFileComplete);
Recipe 23.1Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Browsing for Files
- InhaltsvorschauYou want to let the user browse his local disk(s) for a file (s) to upload.Use the browse( ) method of either a FileReference or FileReferenceList object.Using the browse( ) method of a FileReference of FileReferenceList object, you can open a dialog box that allows the user to browse his local disks for a file or files. The difference between the browse( ) methods of the FileReference and FileReferenceList classes is that the former allows the user to select just one file, while the latter allows the user to select more than one file by holding the Control or Shift key (or the Command key on a Macintosh):
fileReference.browse( );
As with the download( ) method, the browse( ) method can throw errors, and it’s best to handle the errors usingtry/catch. An illegal operation error can occur in one of two scenarios:-
Only one browse dialog box can be open at a time. If a dialog box is already open and you call browse( ), it throws an error of type IllegalOperationError.
-
If the user has configured his global Flash Player settings to disallow file browsing, calling the browse( ) method will throw an error.
This block of code illustrates how to use atry/catchblock to handle an IllegalOperationError thrown when calling browse( ).try { fileReference.browse( ); } catch (illegalOperation:IllegalOperationError) { // code to handle error }Handling the error ensures that Flash Player will not display a default error message to the user (which could be disconcerting to the user).Recipe 23.5Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Filtering Files That Display in the Browser Window
- InhaltsvorschauYou want to filter the type of files that display in the browse dialog box so the user only sees the types of files you want to allow her to upload.Pass an array of FileFilter objects to the browse( ) method.By default the browse( ) method displays a dialog box that displays all files on the user’s filesystem. However, you also have the option of filtering the types of files that are displayed. For example, you may want to display only image files or only text files. You can accomplish this by passing an array of flash.net.FileFilter objects to the browse( ) method.The FileFilter constructor requires at least two parameters:
-
The first parameter determines what displays in the “Files of type” drop-down menu in the browse dialog box.
-
The second parameter determines which file extensions are filtered.
File extensions must be semicolon-delimited, each prepended with an asterisk and a dot. The following constructs a FileFilter object that filters for files with file extensions of .png, .gif, and .jpg:var fileFilter:FileFilter = new FileFilter("Images", "*.png;*.gif;*.jpg");Additionally, you may opt to specify a third parameter of Macintosh file types. As with file extensions, file types are semicolon delimited. When the Macintosh file types parameter is omitted, the file extensions are used as a filter for both Windows and Macintosh files. When the Macintosh file types parameter is specified, the file extensions are used as a filter for Windows files, while they are ignored for Macintosh files in preference of the Macintosh file types. Macintosh operating systems now support file extensions as a way of determining the file type, yet they also continue to support type codes assigned to the files.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Detecting When the User Has Selected a File to Upload
- InhaltsvorschauYou want to detect when the user has selected a file from the browse dialog box.Listen for a
selectevent. Listen for acancelevent to determine if and when the user clicks the Cancel button.When the user selects a file and clicks the Open button from a browse dialog box, the FileReference object dispatches aselectevent of type Event. You can use theEvent.SELECTconstant to add a listener, as follows:fileReference.addEventListener(Event.SELECT, onSelectFile);
When the user has selected a file, the details of that file are immediately available (name,size,createdDate, etc.). For example, as soon as a FileReference object dispatches a SELECT event you can retrieve the filename, as in the following example:selectedFileTextField.text = fileReference.name;
When the user clicks the Cancel button from a browse dialog box, the FileReference object dispatches acancelevent of type Event. You can use theEvent.CANCELconstant to add a listener, as follows:fileReference.addEventListener(Event.CANCEL, onCancelBrowse);
Theselectandcancelevents also work for FileReferenceList objects.Recipe 23.7Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Uploading Files
- InhaltsvorschauYou want to allow users to upload files.Use the upload( ) method of the FileReference object.The upload( ) method of a FileReference object allows you to upload a file to a server by using a server-side script that is configured to accept uploads using HTTP(S). At a minimum, the upload( ) method requires one parameter as a URLRequest object specifying the URL of the script to which you want to send the file data:
var urlRequest:URLRequest = new URLRequest("uploadScript.cgi"); fileReference.upload(urlRequest);All uploads usePOSTwith aContent-Typeofmultipart/form-data. By default, theContent-Dispositionis set toFiledata. The script needs to know theContent-Dispositionvalue so it can read the file data. If the script needs to use aContent-Dispositionother than the default, you can specify a value as the second, optional parameter you pass to the upload( ) method, as follows:fileReference.upload(urlRequest, "UploadFile");
You can only upload a file if the user has selected the file using browse( ). If the user selects a file using a FileReference object’s browse( ) method, then you can call upload( ) after theselectevent occurs. If the user selects files using FileReferenceList, then you must call the upload( ) method for each file in the object’sfileListproperty. ThefileListproperty of a FileReferenceList object is an array of FileReference objects corresponding to each of the files selected by the user.The upload( ) method can throw errors. The possible errors thrown by upload( ) are identical to those thrown by download( ). Additionally, like download( ), the upload( ) method can dispatch security error events and IO error events. See Recipe 23.1 for more details on handling these errors and error events.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Monitoring File Upload Progress
- InhaltsvorschauYou want to monitor the progress of a file as it uploads to your server.Listen for a
progressevent.You can monitor file upload progress, much as you can monitor a file download progress. A FileReference object dispatches progress events when the file is uploading. When the file has completed uploading, it dispatches a complete event. See Recipe 23.3 for details.Recipe 23.3Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Chapter 24: Socket Programming
- InhaltsvorschauSocket connections allow the Flash Player to send and load data from a server over a specified network port. The main difference between socket and server connections in Chapter 20 is that socket connections don’t automatically close after data transfer is complete.When a socket connection is made, the connection stays open until the client (the Flash Player) or the server explicitly closes it. Because of this, sockets enable a special type of communication called data push, which means that the server sends information to the Flash Player at any time without a request coming from the Player itself.Socket connections are typically used to create multiuser applications. An example of one such application would be an online chat room. The chat program might consist of a central chat server with various connected Flash Player clients. Each time a client .swf sends a message to the server, the server determines which client should receive the message and pushes the message to that specific client over the open connection. In this case, the receiving client didn’t ask for the message, but rather the message was simply pushed out to it by the server. When a client closes a connection, the server notifies the other clients that someone has logged off of the system.Two types of socket connections can be made from the Flash Player to a socket server. They are very similar in behavior and operation, but have a few subtle differences. The first is an XML socket connection that is similar to the XMLSocket in previous versions of the Flash Player. New for Flash Player 9 is a binary socket connection.To create an XML socket connection, use the flash.net.XMLSocket class. To create a binary socket connection, use the flash.net.Socket class.XML socket connections are focused around text. The client and server communicate by exchanging XML packets containing data. Actions are carried out by analyzing the contents of the XML packets.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- Introduction
- InhaltsvorschauSocket connections allow the Flash Player to send and load data from a server over a specified network port. The main difference between socket and server connections in Chapter 20 is that socket connections don’t automatically close after data transfer is complete.When a socket connection is made, the connection stays open until the client (the Flash Player) or the server explicitly closes it. Because of this, sockets enable a special type of communication called data push, which means that the server sends information to the Flash Player at any time without a request coming from the Player itself.Socket connections are typically used to create multiuser applications. An example of one such application would be an online chat room. The chat program might consist of a central chat server with various connected Flash Player clients. Each time a client .swf sends a message to the server, the server determines which client should receive the message and pushes the message to that specific client over the open connection. In this case, the receiving client didn’t ask for the message, but rather the message was simply pushed out to it by the server. When a client closes a connection, the server notifies the other clients that someone has logged off of the system.Two types of socket connections can be made from the Flash Player to a socket server. They are very similar in behavior and operation, but have a few subtle differences. The first is an XML socket connection that is similar to the XMLSocket in previous versions of the Flash Player. New for Flash Player 9 is a binary socket connection.To create an XML socket connection, use the flash.net.XMLSocket class. To create a binary socket connection, use the flash.net.Socket class.XML socket connections are focused around text. The client and server communicate by exchanging XML packets containing data. Actions are carried out by analyzing the contents of the XML packets.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- Connecting to a Socket Server
- InhaltsvorschauYou want to establish a connection with a socket server.Use either the Socket.connect( ) or XMLSocket.connect( ) method and listen for the
connectevent to be notified when a connection is made.To connect to a socket server, there are two critical pieces of information that you need to know before attempting to make a connection. The first is the domain name or IP address of the server to which the connection will be made, and the second is the port over which the connection should take place.Whether you are using a Socket or an XMLSocket instance, the connection process is exactly the same; both classes define a connect( ) method that takes two parameters:host-
A string value specifying the host to connect to, either with a domain name such as
www.example.com, or with an IP address such as192.168.1.101. To connect to the web server the Flash movie is being served from, passnullinstead of a string hostname. port-
An int value specifying the port number that should be used to connect to the host. The port value must be at least 1024, unless the server has a policy file specifically allowing ports less than 1024.
Because of the asynchronous nature of socket programming in Flash, the connect( ) method does not wait for a connection to happen before continuing to the next line of ActionScript code. If you try to interact with a socket before a connection has been fully established, you’ll encounter unexpected results and your code won’t work correctly.The proper way to connect to a socket is to first add an event listener for theEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Sending Data
- InhaltsvorschauYou want to send data to a socket server.For Socket objects, use the write methods ( writeByte( ), writeUTFBytes( ), etc.) to write the data to the buffer and call flush( ) to send the data. For XMLSocket objects, use the send( ) method.The Socket and XMLSocket classes define different APIs for sending data to the socket server. Let’s look at the Socket API first.When you want to send data to a socket server using a Socket object, you first must write the data to the buffer. The Socket class defines a slew of methods for writing data. Each of the methods writes a different type of data (or writes the data differently). The methods are writeBoolean( ), writeByte( ), writeBytes( ), writeDouble( ), writeFloat( ), writeInt( ), writeMultiByte( ), writeObject( ), writeShort( ), write- UnsignedInt( ), writeUTF( ), and writeUTFBytes( ). Most of the methods accept one parameter of the type implied by the name of the method. For example, writeBoolean( ) accepts a Boolean parameter and writeByte( ), writeDouble( ), writeFloat( ), writeInt( ), writeShort( ), and writeUnsignedInt( ) accept numeric parameters. The writeObject( ) method accepts an object parameter that must be serializable to AMF format. The writeBytes( ) method allows you to pass it a ByteArray parameter along with offset and length parameters. For example, the following calls writeBytes( ) passing, it a reference to a ByteArray object and specifying that it should write all the bytes (starting at offset 0 with length equal to the length of the ByteArray):
socket.writeBytes(byteArray, 0, byteArray.length);
The writeUTF( ) and writeUTFBytes( ) methods allow you to write strings. Each method accepts a string parameter. TheEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Receiving Data
- InhaltsvorschauYou want to read data from a socket server.For Socket instances, subscribe to the
socketDataevent and invoke one of the read methods, such as readByte( ) or readInt( ), in the event handler, making sure not to read pastbytesAvailable.For XMLSocket instances, subscribe to thedataevent and interpret the XML data received inside of the event handler.Receiving data from a socket connection depends on the type of socket you use. Both Socket and XMLSocket are capable of receiving data from a server, but they do so using slightly different techniques. Let’s focus on how the Socket class works first before discussing XMLSocket.As you’ve learned in the introduction to this chapter, sockets in Flash behave asynchronously. Therefore, it’s not possible to simply create a socket connection and attempt to read data from the socket right away. The read methods don’t wait for data to be transferred from the server before returning. Instead, you can only read data from a socket after the client has already downloaded the data from the host server. It is an error to try and read data from a Socket before any data is available.To know when data is available to be read, thesocketDataevent is broadcasted from Socket instances. By adding an event listener for thesocketDataevent, your event handler is invoked anytime there is new data received from the socket server. Inside the event handler is where you write code to read and interpret the received data.To read the data sent from the server, the Socket class provides a number of different read methods, depending on the type of data you want to read. For instance, you can read a byte with the readByte( ) method, or read an unsigned integer with the readUnsignedInt( ) method. See Table 24-1 for a list of the different datatypes that can be read from the socket server, what the return value is, and how many bytes theEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Handshaking with a Socket Server
- InhaltsvorschauYou want to do handshaking with a socket server and need to know what the received data’s context is to know how to process it.Create different constant variables to represent states of the protocol. Use the constants to map particular processing functions with the corresponding state. In a
socketDataevent handler, call the appropriate function by invoking it through the state map.A common scenario when connecting to a socket is going through a handshake process. Typically, the server initially sends data to the client. The client then responds to the data in a particular manner, and the server responds again accordingly. This entire process repeats until the handshaking is complete and a “normal” connection is established.It gets difficult to process the response from the server because thesocketDataevent handler does not keep track of context. That is, there is no “why” sent along with the server response, or no “this data is in response to” processing directive. Knowing how to process the response from the server is not usually something that can be gathered through the response itself, especially when the response varies. Perhaps one response returns two bytes and another returns an integer followed by a double. You can begin to see how this presents itself as a problem.The solution is to create various state constants to represent the different contexts in which the server sends data to the client. By associating each of these constants with a particular function to handle the data, you can easily call the correct processing function based on the current state of the protocol.Consider the following handshaking scenario that happens when you connect to a socket server:-
The server responds immediately when it connects with an integer representing the highest version of the protocol that the server supports.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Disconnecting from a Socket Server
- InhaltsvorschauYou want to disconnect from a socket server, or be notified when the server disconnects you.Invoke the Socket.close( ) or XMLSocket.close( ) method to explicitly close the connection, or listen for the
closeevent to be notified when the server closes the connection for you.A general rule to follow when programming is to clean up after yourself. That is, if you create an object, you should also delete it when it is no longer necessary. In this case, whenever you connect to a socket server, you should explicitly close the connection when you’re done. Leaving an unused socket connection open is a waste of resources and should be avoided if at all possible. If you don’t close a connection, then the server may continue to keep an open socket connection that is not being used, which can quickly cause a server to overrun its allotment of allowed socket connections.Closing a socket connection is the same for both Socket and XMLSocket instances. All you need to do is invoke the close( ) method on the socket instance:// Assume socket is a connected Socket instance socket.close( ); // Disconnect from the server
Using an XMLSocket is exactly the same:// Assume xmlSocket is a connected XMLSocket instance xmlSocket.close( ); // Disconnect from the server
The close( ) method is useful for letting the server know that the client wants to disconnect. To be notified when the server closes the connection on its own, you should listen for thecloseevent by calling addEventListener( ) on the Socket or XMLSocket instance withEvent.CLOSEas the event type; for example:var socket:Socket = new Socket( ); // Add an event listener to be notified when the server disconnects // the client socket.addEventListener( Event.CLOSE, onClose );Invoking theEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Handling Socket Errors
- InhaltsvorschauYou want to handle errors that might occur when using sockets.Use
try/catchto handle I/O and end of file (EOF) errors.Both the Socket and XMLSocket classes behave similarly in regard to errors and error events. When calling the connect( ) method, Socket and XMLSocket objects can throw an error of type SecurityError when either of the following conditions is true:-
The .swf is classified as local untrusted.
-
The port number is higher than 655535.
When calling send( ) (XMLSocket) or flush( ) (Socket), the method can throw an error of type IOError if the socket isn’t connected. Although you can (and likely should) place the send( ) or flush( ) method calls within try/catch blocks, you should not rely on try/catch blocks as part of your application logic. Rather, use an if statement to test whether or not the socket object’s connected property is true before calling send( ) of flush( ) if you want such a test to be part of the application logic. For example, the following uses anifstatement as part of the application logic to call a connectToSocketServer( ) method if the Socket object isn’t currently connected. It also uses atry/catchblock to write to a log if the flush( ) method throws an error:if ( socket.connected ) { try { socket.flush( ); } catch( error:IOError ) { logInstance.write( "socket.flush error\\n" + error ); } } else { connectToSocketServer( ); }All of the Socketreadmethods can throw errors of type EOFError and IOError. EOF errors occur when you try to read data, but nothing is available. I/O errors occur when you try to read from a socket that is closed.In addition to the errors thrown by methods of theEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Appendix 1: Unicode Escape Sequences for Latin 1 Characters
- InhaltsvorschauTable A-1 lists the characters in the Latin 1 character repertoire, with Unicode equivalents in the range of
U+0000toU+00FF(that is, C0 Controls, Basic Latin, C1 Controls, and Latin 1 Supplemental). It is reproduced from Appendix B of ActionScript for Flash MX: The Definitive Guide with the permission of the author, Colin Moock.The table’s first column (labeled Dec) lists each character’s code point in decimal (the standard ASCII or Latin 1 value), the second column provides the Unicode escape sequence for the character, and the third column describes or shows the character itself.Table : ISO 8859-1 (Latin 1) characters and Unicode mappings Dec Unicode Description Dec Unicode Description 0 \\u0000 [null] 15 \\u000f [shift in] 1 \\u0001 [start of heading] 16 \\u0010 [data link escape] 2 \\u0002 [start of text] 17 \\u0011 [device control one] 3 \\u0003 [end of text] 18 \\u0012 [device control two] 4 \\u0004 [end of transmission] 19 \\u0013 [device control three] 5 \\u0005 [enquiry] 20 \\u0014 [device control four] 6 \\u0006 [acknowledge] 21 \\u0015 [negative acknowledge] 7 \\u0007 [bell] 22 \\u0016 [synchronous idle] 8 \\u0008 [backspace] 23 \\u0017 [end of transmission block] 9 \\u0009 [horizontal tabulation] 24 \\u0018 [cancel] 10 \\u000a [line feed] 25 \\u0019 [end of medium] 11 \\u000b [vertical tabulation] 26 \\u001a [substitute] 12 \\u000c [form feed] 27 \\u001b [escape] 13 \\u000d [carriage feed] 28 \\u001c [file separator] 14 \\u000e [shift out] 29 \\u001d [group separator] 30 \\u001e [record separator] 66 \\u0042 B 31 \\u001f [unit separator] 67 \\u0043 C 32 \\u0020 [space] 68 \\u0044 D 33 \\u0021 ! 69 \\u0045 E 34 \\u0022 ” (straight quotes) 70 \\u0046 F 35 \\u0023 # 71 \\u0047 G 36 \\u0024 $ 72 \\u0048 H 37 \\u0025 % 73 \\u0049 I 38 \\u0026 & 74 \\u004a J 39 \\u0027 ’ (straight apostrophe) 75 \\u004b K 40 \\u0028 ( 76 \\u004c L 41 \\u0029 ) 77 \\u004d M 42 \\u002a * 78 \\u004e N 43 \\u002b + 79 \\u004f O 44 \\u002c , (comma) 80 \\u0050 P 45 \\u002d – (minus) 81 \\u0051 Q 46 \\u002e . (period) 82 \\u0052 R 47 \\u002f / 83 \\u0053 S 48 \\u0030 0 84 \\u0054 T 49 \\u0031 1 85 \\u0055 U 50 \\u0032 2 86 \\u0056 V 51 \\u0033 3 87 \\u0057 W 52 \\u0034 4 88 \\u0058 X Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Zurück zu ActionScript 3.0 Cookbook
