Using the Actions Panel
The Actions panel along with the Script window are at the heart of the scripting you'll be doing. All external coding is done in the Script windows, and the internal code preserved in FLA files is created in the Actions panel. Because the Actions panel in Flash Pro has changed slightly since the last version and some readers are new to its use, the following quick overview serves as both a review and a brief introduction to the Actions panel.
To familiarize you with using the Actions panel, this next little project is handy if you're trying to figure out what 25 degrees Celsius is in Fahrenheit degrees. It uses two text fields and a couple buttons, but otherwise it's all coded. Don't worry about understanding the conversion algorithms. Also, this project doesn't employ any classes; it's just a little warm-up exercise. Figure 3.7 gives you an idea of how the developmental environment looks to help you position the different parts.
Figure 3.7 This application uses ActionScript to convert values between Celsius and Fahrenheit.
Use the following steps to re-create the application:
-
Open a new Flash document and create four layers. From top to bottom, name them Actions, Text Fields, Buttons, and Background.
-
Use the color code #6A0012 for the background color. Select the Background layer and draw a rectangle with a 10-point stroke with the dimensions W=385, H=280. Use #F0DD38 for the stroke color and #D68614 for the fill color. Center the rectangle horizontally and vertically on the Stage. Lock the Background layer.
-
Select the Text Fields layer. Using the Text tool, add two input text fields, positioning one above the other. Select the top field. In the Property Inspector, type the instance name far_txt and then do the same for the bottom text field, using the instance name cel_txt. If it's not selected, click the Show Border Around Text button in the Property Inspector. Lock the layer.
-
Select the Buttons layer and draw a circle with a 22.2 diameter using a 2-point stroke. The stroke color is #6A0012 and the fill color is #838F8E. Select the drawing and press the F8 key to open the Convert to Symbol dialog box. Choose Button for the Type setting and name it what you like. Open the Library panel (Ctrl+L/Cmd+L) and drag a second instance of the button to the Stage. Place both buttons between the two input text fields. (Refer to Figure 3.7 for a guide.) Provide the instance name convert_btn for the button on the left and reset_btn for the button on the right. Lock the layer.
-
Unlock the Background layer and add labels using the Text tool and static text, as shown in Figure 3.7. Lock the layer.
-
Click the first frame of the Actions layer and add the following script:
//Reset to blank reset_btn.onPress = function() { far_txt.text = ""; cel_txt.text = ""; }; //Convert C/F and F/C convert_btn.onPress = function() { if (cel_txt.text == "") { //Fahrenheit to Celsius var far2cel:Number = Math.round((100/(212-32)*(Number(far_txt.text)-32))) _*100/100; cel_txt.text = far2cel; } else { //Celsius to Fahrenheit var cel2far:Number = Math.round((((212-32)/100*Number(cel_txt.text)+32) _*100)/100); far_txt.text = cel2far; } };
To test the movie, enter a number in either input text field and click the Convert button. The application converts the value to the opposite temperature unit of measure. Before each conversion, click the Reset button.
Writing Code
Open the Actions panel by pressing F9. The panel has three parts: On the left are the Actions toolbox, where the code can be found, and the Script navigator, which shows icons of different actions and objects in your document. The right side of the panel contains the Script pane, where you write your code.
Above the Script pane are several different buttons to aid you in writing code (see Figure 3.8).
Figure 3.8 The Actions panels buttons.
Table 3.1 briefly describes what each of these buttons do along with comments as to their relative usefulness based on the author's experience, but feel free to use them in any way you want.
Table 3.1 Code Aid Buttons
Button |
Description |
Add Item |
I rarely use this button. When you click it, a series of menus and submenus let you fish for the code you want. Using this button may aid some, but it's really a residue of early versions of Flash ActionScript, and more of a hindrance than help. If you want to automatically add code, you will find it far easier to use the Actions toolbox and double-click the term you want to use. |
Find |
Use this button in longer scripts when you want to find a term. Just click the button and type the term you're trying to find. |
Find & Replace |
This button works like a find-and-replace operation in a word processor. Type the word to find and the replacement word. The only limitation of this button is that you can't select a portion of the script (as you can in a word processor) and just find and replace terms in a limited section of a script. So remember, when you use the Find & Replace button, everything in the script will be changed. (Keep the Ctrl+Z [Undo] shortcut handy when using this option.) |
Insert Path |
This is another one of those buttons left over from earlier versions of Flash that may have limited utility. Where you have lots of addressable objects on the Stage and want to find the path to an object, this can come in handy. With the new Script Navigator, though, this button has less use than before. |
Check Syntax |
Before you test your movie, give this button a click. If it finds errors, it will show the nature of the errors in the Output window. Don't rely too heavily on the Check Syntax button, though, because your code can have correct syntax and still not work the way you want. |
Auto Format |
This is one of my most-used buttons. It cleans up your code so that it's easier to read. If you have an error in your code, this button won't format it for you, so you then must click the Check Syntax button. Usually I find it easier to click this button first rather than the Check Syntax button because if there are no errors, you'll have your code nicely formatted. |
Show Code Hint |
Even though this button might be thought of as a beginner's button, I use it all the time. With strong typing in variables in Flash Pro, this button becomes indispensable. For example, if you type var myHotVar:, a list of data types appears. Although user-defined types won't appear, you'll find that getting used to strong data typing, along with the rest of ActionScript 2.0, is greatly aided by the code hints. |
Reference |
If you select a term in the script and click the Reference button, the Help panel appears with information about the selected item. This is extremely handy, especially when you're getting to know the new code used for the ActionScript 2.0 components. |
Debug Options |
The main debug option you'll probably use is setting breakpoints. A breakpoint allows you to stop a SWF in the middle of being played where the breakpoint has been placed. You can also remove a breakpoint using this same button. (Generally, I find it easier to just click the line number where I want a breakpoint, and one is inserted.) |
View Options |
This button opens a menu to select set-and-forget options. Included are View Esc Shortcut Keys, View Line Numbers, and Word Wrap. All these options are helpful, and line numbers are essential when you begin writing longer code. I use Word Wrap, but it can be toggled off if you have an especially long line of code that's better viewed using the horizontal scrollbar at the bottom of the Script pane. |
Pin Script |
When you have several objects on the Stage and you keep forgetting their instance names and have to click them to recall their names in the Property Inspector, you'll love this feature. When you "pin" a script, it stays put while you click different objects and layers. With multiple scripts, it's possible to use multiple pins. Pin Script is a toggle button, so you can just click the pin icon to turn it on or off. |
The pop-up menu in the upper-right corner of the Actions panel contains duplicates of the Actions buttons and preferences found elsewhere in Flash. However, it has a number of handy options you can use even if many are redundant (see Figure 3.9).
Figure 3.9 The Actions panel's pop-up menu provides a wide number of options you will find valuable.
Variables
Case-Sensitive Code
An important new feature in ActionScript 2.0 not found in ActionScript 1.0 is case-sensitive code. Writing code in ActionScript 1.0 meant that variable names only had to be spelled the same to be considered the same instance of the variable. Hence, myVariable, MyVariable, and myvariable are treated as equivalents in ActionScript 1.0, but in ActionScript 2.0 they're considered to be different variables. When writing code, be sure to observe case sensitivity.
Like all computer languages, ActionScript 2.0 variables are data containers. However, unlike ActionScript 1.0, the data that a variable can contain in ActionScript 2.0 must conform to a type. For example, if a variable is declared as a String type of data, when you place a Number type in the variable, the number will be treated as a string. In ActionScript 1.0, a variable changes depending on its contents. Most other OOP languages, such as Java and C++, have a similar form of data typing, called strict or strong data typing. To declare a variable, you include the type of variable using this format:
var variableName:DataType = value;
For example,
var moneyIn:Number = 123456
declares the variable named moneyIn as a Number and assigns it the value 123456. If you later decided to assign a String to the moneyIn variable, you'll get a Type Mismatch error. Try the following script to see what happens:
var moneyIn:Number = 123456; moneyIn="Dough"; trace(moneyIn);
The Output window signals a Type Mismatch error. However, you can assign hexadecimal values to a Number type variable. The following script works without an error because the hexadecimal value is automatically translated into a decimal value:
var moneyIn:Number = 123456; moneyIn=0xFFFF; trace(moneyIn); //Output = 65535
Code Hints to the Rescue
You should write your scripts with Code Hints enabled in the Actions panel and Script window. This way, when you declare your variables, as soon as you type the colon at the end of var variableName:, a list of all the data types appears. While you're getting used to the different data types available, you'll find this pop-up menu invaluable.
Data Types
The most general data type categories include the following:
-
Primitive
-
MovieClip
-
Object
The MovieClip data type is the only one that refers to a graphic element you create on the Stage. It can be a little confusing because movie clips are objects, and you can declare a movie clip object to be either an Object or MovieClip type of data. Object data types can either be built in or user created (custom). A detailed categorization of data types is shown in Table 3.2.
Table 3.2 Data Types and Assigned Values
Data Type |
Description |
String |
Refers to sequence of characters enclosed by quotation marks. For example, var someName:String = "\"Delia\"" returns "Delia". |
Number |
Double-precision floating-point value. Responds to math operators. |
Boolean |
Includes values of true and false or 1 and 0. |
Object |
A collection of properties that have variable-like values. You can arrange objects inside one another (nesting) and access them through the path using dot (.) operators (for example, ObjectInstance.prop1.prop2.prop3). All methods in the Object data type are available to object instances. |
Null |
This data type has a single value, null, which is the same as no value. |
MovieClip |
This data type refers to movie clip symbols in a Flash document. All properties, methods, and other controls are available to instances of the MovieClip data type. |
Undefined |
When an existing variable has no value, it's treated as undefined, which is the single value of this data type. |
When you type a data type, the pop-up menu shows far more data types, including all the built-in objects and components.
You can add all custom classes as data types. For example, suppose you have a class named Clients. This is a custom class that won't show up in the pop-up menu when you're declaring a variable. For example, the following script is perfectly acceptable:
var FarShores: Clients = new Clients();
Therefore, keep in mind that although the pop-up menu is important for getting to know the built-in data types, all custom classes can be used as data types.
Converting Data Types
Sometimes you will want to convert a variable from one data type to another. One of the more common situations where such a conversion would be desirable occurs when using input text fields. All data entered into a text field is automatically typed as strings. When using text fields for entering numeric characters requiring math operations, you need to make data type conversions prior to the math operations. The following code shows an example of making such a conversion:
btn.onPress = function() { var productCost:Number = Number(product_txt.text); output.text = productCost += (productCost*.05); };
Likewise, sometimes you need a double conversion. The following script begins with text to be converted to a number to be converted to a string for hexadecimal output:
btn.onPress = function() { var conHex:Number = Number(product_txt.text); output.text = String(conHex.toString(16)); };
You can use any of the conversion functions in Table 3.3 to convert data types.
Table 3.3 Conversion Functions
Function |
Description |
Number() |
Converts data into real numbers. This function is especially useful in converting numbers from input text fields into real numbers. |
Array() |
Converts contents into array elements; for example, Array("nuts","bolts", 21);. |
Boolean() |
Converts to true/false but also 1/0; for example, Boolean("apples"=="oranges");. |
Object() |
Converts numbers, strings, and Booleans to objects; for example, Object("A String");. |
String() |
Converts numbers, Booleans, and strings to text (for example, a Boolean becomes the string true or false). An object is returned as a string representation of the object. Movie clips are returned as paths using slash syntax (not available in ActionScript 2.0). Also, as illustrated earlier, you may need to make more than a single conversion, even in a relatively simple operation. |
To OOP or Not to OOP
To OOP, or not to OOP: That is the question: Whether 'tis nobler in the compiler to Grind the code with objects, properties, and methods, Or to sling a sea of procedures, And by so doing end the script?
With apologies to Shakespeare, therein lies the nub and rub of whether to use OOP. Computer engineers may see the question as moot because the benefits of OOP are so many and (to them) so obvious. As noted at the beginning of this chapter, OOP indeed has much to offer, and as an approach to big projects with multiple programmers, OOP has become a virtual necessity.
However, is OOP really necessary for little programs that are often associated with modules used for Flash pages for the Web? After all, if a few lines of code will solve the problem and get the job done, why take the long way around, creating a class in an AS file and then writing code in the Actions panel that uses the code that could have been created as procedures in the first place? The truth of the matter is that a few procedures often do the job just fine, and you can rest assured that the OOP police won't be at your doorstep if you knock out a simple application without even thinking about OOP. In the real world of business development where a client needs a module immediately and doesn't know OOP from elephants, no one's going to know whether your code is OOP compliant or not. (Well, maybe some OOP Nazi whose idea of a good time is to decompile code to check for good OOP practices; however, those guys usually can't get out of the asylum long enough to be a real problem.)
Such exigencies aside, where using procedural programming to meet a deadline is more than a convenience, developing good OOP practices has other consequences than being politically correct. Using OOP makes me stop and organize my work. Put otherwise, it forces me to plan. Procedural programming practices allow the coder to muddle through with a lick and a promise, and usually something workable comes out the other end. As projects grow in size and complexity, especially if site maintenance requiring regular updates and changes is built in to a contract, the fly-by-the-seat-of-your-pants methods begin to take their toll. Without foresight and planning, every little change could require major program rewriting. So rather than spending a little time at the onset of a project planning, the developer finds himself tacking together an increasingly onerous site.
A friend of mine who is a self-taught programmer latched onto OOP and modular programming on his own. He explained that it just didn't make any sense to spend a lot of time working out code only to have to redo the same or similar code for every client. So, he began making classes from his procedural code. He took what worked well, and then taking the core algorithms from the code, he reworked it in OOP format. He planned way ahead. Instead of waiting for a client to give him specs for a new project, he culled the needs of his former clients and created classes and modules that dealt with typical site requirements. He was able to meet his clients' requirements much quicker but also with better-quality code. Because most of the modules and classes for typical needs were already built, he could spend his time meeting unique client needs.
My advice is to get used to OOP at your own pace. Because OOP is as much an attitude as a set of procedures, start with the simpler aspects of OOP. Instead of wringing your hands about whether you really understand polymorphism, just take little steps. A very first step is to stop and think about a project as being made up of different objects with certain characteristics and behaviors. Next, rather than beginning a project in the Actions panel or even the Script editor, begin with pencil and paper. Sketch out client requirements and think about the objects you'll need in your program. As you take these steps, you'll ease into OOP and write far better programs.
Operators
ActionScript 2.0 works with a rich set of operators for generating a wide set of actions. The Flash MX Professional 2004 operators are organized into six subfolders with two general operators outside of all but the Operators folder.
For those unfamiliar with ActionScript 2.0 and operators, the following examples are included to provide a guide in the use of operators from different categories.
General
The two general operators are used in several different situations. The following script shows uses for both:
var Price:Number = 123; var Discount:Number = 25; //Double quotes var Buck:String = "$"; //Parentheses var total:Number = (Price-Discount)+(Price-Discount)*.06; var formatIt:String = Buck+total; output.text = formatIt; //Displays $103.88
You'll also find parentheses in conditional statements, but their use still serves to group a number of statements. The single quote (') acts the same as a double quote in designating a string.
Arithmetic Operators
This set of operators is fairly straightforward. The only unusual operator is the addition sign (+) because it is used both for concatenation of strings and adding numeric values, as mentioned earlier. For arithmetic operations, the data type must be Number or some other data type that has real values. (The string "2" cannot be divided, for example, whereas the number 2 can.) The following example shows a typical application of these operators:
var total:Number = (7 *5) + 55 - (7/2);
The modulo (%) operator can be especially useful for formatting dollars and cents. It divides the left operand by a specified modulo value and returns the remainder. The following example shows how a number can be reformatted using the modulo operator:
var totalPurchase:Number = 432.5456; var dollars:Number = Math.floor(totalPurchase); //Use modulo var cents:Number = Math.round(totalPurchase*100)%100; var zero:Boolean = cents<10; if (zero) { var cents:String = "0"+String(cents); } output.text = "$"+dollars+"."+cents;
Assignment
Assignment operators have two forms. Typically, the single equal sign (=) serves to assign values to variables. This is a single assignment operator. Compound assignment operators assign the value of the left operand with the results of the operation between the left and right operands. For example, the following shows adding tax to a product using a compound operator:
var tax:Number = .06; var price:Number = 6.70; //Compound assignment price += tax; output.text = "$"+price;
The add and assign (+=) compound operator adds the value of the price and tax variables using the compound operator shortcut rather than the following:
price = (price + tax);
Compound operators can be seen as ways to complete two operations with a single operator.
Bitwise Operators
To understand using bitwise operators, you need to take a look at a good book on binary math.
Some quick practical applications can be seen in shifting bits left and right by a given value. For example, a shift to the left by 1 (<<=1) doubles a number, whereas a shift to the right by 1 (>>=1) rounds the value by terminating all fractions. The following example illustrates this process:
var first1:Number=18.64; var left1:Number= (first1 <<=1) var right1:Number=(first1 >>=1) //Output value 18 output.text=right1; //Output value 36 output2.text=left1;
Some programmers make good use of bitwise operators, but most programmers and programs don't require any bitwise operators. However, if you need them, they're available.
Comparison Operators
Comparison operators are typically employed in conditional statements and Boolean variables. The test for equality (==) is often confused with the assignment (=) operator, so you need to pay attention when using one or the other. For example, the following script compares the contents of two variables:
var Num:Number = 7; var Str:String = "7"; if (Num == Str) { trace("same"); } else { trace("diff"); }
Although the string "7" and the number 7 are different, the test for equality (==) finds them to be the same; however, if you use the test for strict equality (===), they're found to be different. Strict equality tests for both value and data type, whereas the equality operator only tests for value. All the operators defined as "strict" test for both data type and data contents.
Logical Operators
Not counting the bitwise operators, ActionScript 2.0 has only three logical operators. They return a Boolean value. Like comparison operators, these operators are typically found in conditional statements. The following example uses all three operators:
var cats:String = "Meow"; var dogs:String = "Bark"; var fido:String = "My Doggy"; var bowser:Boolean = (cats == dogs); if (!bowser && cats == "Meow" | | dogs == "Meow") { trace("It's true!"); }
The logical NOT operator (!) along with both the logical AND (&&) and logical OR operators deal with Boolean logic.
Miscellaneous Operators
Three types of operators are stored in the Miscellaneous Operators folder. First are the increment (++) and decrement (--) operators. These operators serve to add 1 to or subtract 1 from variables. This example adds 1 to the value of x each time it passes through the loop:
for (var x=1; x<12; x++) { trace(x); }
Second, this folder contains a ternary operator (?:). This unusual operator acts like a shortcut for a conditional statement with an else statement. For example, the third line of the script
var income:Number = 5000; var bills:Number = 4300; var funds = (income>bills) ? trace("Ok") : trace("Yikes!");
does the same thing as the following script:
if (income > bills) { trace("Ok") }else{ trace("Yikes!") }
The third type of operator in the Miscellaneous folder deals with comparative instances of data and classes. The typeof operator returns the data type of a variable. However, the instanceof operator generates a Boolean result relative to the object being queried. For example, the following script returns true because whatsNew is an instance of the String class:
whatsNew= new String("Day") instanceof String; trace(whatsNew)
The instance name, whatsNew, contains a Boolean value and not the string "Day". That's because the operator instanceof directs the outcome and not the instantiation of the String object.
Finally, the void operator serves to create an undefined variable from a defined one. For example, the following script creates a string variable, called idNow, and then declares a second variable, cancelId, using the void operator with the first variable:
var idNow:String="Cimbel"; trace(idNow) var cancelId=void(idNow); trace(cancelId);
When using the void operator, don't use the Void data type. The void operator and Void data type are different ActionScript 2.0 terms. For example, the following line generates an error:
var cancelId:Void=void(idNow);
The Void data type is used with the :(type) operator in developing classes.
Built-in Classes and Objects
In the first part of this chapter in the discussion of OOP, one conception of classes and objects posits that objects are instances of classes. For the sake of both clarity and consistency, all references to classes are either built-in classes, such as those listed in the Built-in Classes folder in the Actions toolbox in the left side of the Actions panel, or custom classes. Objects are simply instances of either the built-in or custom classes.
This section reviews the concepts of built-in classes in ActionScript 2.0 and their constituents. As noted in the OOP discussion, an object, and hence a class, is made up of properties and methods. However, some built-in classes also include constants, events, listeners, and even other objects. To demonstrate each of these class elements, samples from several different built-in classes in the following subsections examine the meaning and use to the parts used with the classes.
Properties
Most, but not all, built-in classes have properties. Some classes, such as Boolean and Date, only have methods and a constructor but no properties. More typically, though, you'll find classes associated with a few or several properties. For instance, the String class has only one property, length, whereas the Button class contains 23 properties.
You use a property with an object by referencing the object's instance name and assigning different values to the property. This is pretty much like assigning values to variables. For example, the following script uses properties from the TextField class in an object with the instance name output_txt:
output_txt.text = "Text here"; output_txt.textColor = 0x00ff00; output_txt.backgroundColor = 0xffff00; output_txt._x = 250; output_txt.borderColor = 0x0000aa;
Figure 3.10 shows the Properties subfolder for the TextField class.
Figure 3.10 Built-in class properties.
In the preceding script, you may have noticed that the instance name has the extension or suffix _txt. This extension is important because it triggers the code hints for all the class elements, including properties, methods, events, and listeners. Several classes have these special suffixes, as shown in Table 3.4.
Table 3.4 Suffixes Used to Automatically Trigger Code Hints
Class Name |
Extension |
Array |
_array |
Button |
_btn |
Camera |
_cam |
Color |
_color |
ContextMenu |
_cm |
ContextMenuItem |
_cmi |
Date |
_date |
Error |
_err |
LoadVars |
_lv |
LocalConnection |
_lc |
Microphone |
_mic |
MovieClip |
_mc |
MovieClipLoader |
_mcl |
PrintJob |
_pj |
NetConnection |
_nc |
NetStream |
_ns |
SharedObject |
_so |
Sound |
_sound |
String |
_str |
TextField |
_txt |
TextFormat |
_fmt |
Video |
_video |
XML |
_xml |
XMLNode |
_xmlnode |
XMLSocket |
_xmlsocket |
Using the class suffixes makes learning and applying properties, classes, events, listeners, and other class elements much easier.
Constants
Constants associated with classes work differently than properties. Constants are invariable, and they must be assigned to a variable as part of a class and not an instance of the class. For example, the following script shows the correct way to assign the value of pi to a variable:
var circleBuild:Number = Math.PI; var radius:Number = 20; var circleArea:Number = circleBuild*(radius*radius); trace(circleArea);
However, if you attempt to first create a Math object and assign the constant to the object, the attempt fails. For example, the following does not work:
var circleBuild:Math = new Math; var radius:Number = 20; var circleArea:Number = circleBuild.PI*(radius*radius); trace(circleArea);
Keep in mind that constants associated with classes need to be passed to variables using the actual class name and constant, and not instance names of the class.
Methods
Depending on the class and method, you'll encounter many different settings and parameters. Methods associated with a class work very much like properties, but methods tend to require values assigned for arguments rather than assignments of values. For example, the following script works with two instances of the MovieClip class, called arrow_mc and target_mc, created on the Stage using the hitTest method:
for (x=20; x<500; x += 10) { _level0.arrow_mc._x = x; if (_level0.arrow_mc.hitTest(target_mc)) { _level0.target_mc._alpha = 20; } }
Using the dot (.) syntax, the method is simply attached to the object (instance name) with the necessary parameters filled in. Thus, the line segment
arrow_mc.hitTest(target_mc)
provides all the necessary information for the hitTest method to be implemented.
Events
Events associated with a class are unique to that class, and although some classes may have the same method names, they may behave very differently. An event is accessed in the same way as methods and properties, using the dot syntax. For example, using a button object created on the Stage, the following script shows a halted playhead awaiting an event to go to and stop at a frame labeled products:
stop(); products_btn.onPress = function() { gotoAndStop("products"); };
Most events are triggered by a user action, such as a mouse event. However, other events are triggered by events that occur within the system, such as an external file loading. For instance, one of the LoadVars() class's events is onLoad. The following script illustrates how to use this event:
textHere = new LoadVars(); textHere.onLoad=function() { output_txt.text=myExternalStuff; }; textHere.load("ExternalFile.txt");
The LoadVars.load method starts the process, and once the file has been loaded, the onLoad event is triggered along with the unnamed function to place the text into a dynamic text field named output_txt.
Listeners
Listeners are more important in Flash MX Professional 2004 than in previous versions of Flash because they're used with components. In Flash MX, change handlers were employed, but now listeners have replaced the change handlers to report an event. If you look at the classes in the Actions toolbox, you'll notice that some classes include listeners. For example, the Key class has two listeners: onKeyDown and onKeyUp.
To use these listeners, you first need to construct an object that can be used to hold them. Then, using the addListener() method, you use the object as an argument. For example, the following script uses the onKeyDown listener:
var hearKey:Object = new Object(); //onKeyDown is Key class listener hearKey.onKeyDown = function() { if (Key.isDown(Key.SPACE)) { trace("Space bar pressed"); } }; Key.addListener(hearKey)
Other classes have different listeners, and all class-related listeners require an Object class instance for you to use them.
Objects
As noted in the discussion of OOP near the beginning of this chapter, objects are made up of properties and methods, but they can contain other objects as well. One class that contains objects is the System class. Two objects are in the System class: capabilities and security.
The reference to an object within an object is simple and straightforward. The object within the object follows the class name. For example,
System.security.allowDomain("http://www.sandlight.com");
uses the System class and the security object, which contains the allowDomain() method. In the same way that dot syntax is used to reference an object's properties and methods, it is used to reference an object within a class instance in its place in the hierarchy. When there's a direct reference to a method, the method follows the class. For example, the line
System.showSettings(2);
displays the Flash Player Settings panel for the microphone settings. The line doesn't reference the security object.
Basic Procedural Structures
This section examines the basic procedural structures used in ActionScript 2.0. All these structures are employed in creating the different OOP structures and represent the most basic fundamentals of program structures. They closely resemble similar structures in other languages.
Sequence
The sequence structure in ActionScript 2.0 is simply the code that executes in order, one after another. In its most elementary form, the sequence is simply a list of statements. For example, the following sequence places text in different instances of text fields:
name.text = "Joe Smith"; address.text = "123 Elm Street"; city.text = "Taft"; state.text = "CT";
A more important use of sequences is where one set of events needs to precede another. For example, in creating an instance of a built-in class, the sequence doesn't include first creating an external AS file, but to use a class's methods and properties, the construction sequence requires that an instance of that class be constructed first before any of its methods or properties can be used. Consider the following example:
//Construct instance of String class var tracker:String = new String("Chance favors the prepared mind."); //Employ Class property length var howLong:Number = tracker.length; trace(tracker+" has "+howLong+" characters.");
Here, a string object first needs to be created. Then the length property can be used in the next line. Finally, both the new object and the variable holding its length can be employed in a third line. The sequence requires that order, and if a step in a sequence is missing, the script either will not execute or won't execute as intended.
Loop
Loop structures in Flash are similar to most other languages (see Statements, Conditions/Loops in the Actions toolbox). Loops in Flash can be divided into two classes: for loops and while loops. The for loop has two types: for and for..in. The while loop also has two types: while and do while.
The basic for loop has the following structure:
for(counter=N; end condition; increment/decrement counter) { //statements }
The counter represents a variable used to set a beginning value, a flag to set the termination of the loop, and an operator and value (if needed) to increase or decrease the value of the counter. For example, the following loop generates the output of an array:
var playOffs:Array = new Array(); playOffs.push("Marlins", "Cubs", "Yankees", "Red Sox"); for (x=0; x<playOffs.length; x++) { trace(playOffs[x]); }
The for..in loop iterates through an object's properties or, in the case of an array, its elements. In using the preceding example, the for..in loop is substituted for the for loop:
var playOffs:Array = new Array(); playOffs.push("Marlins", "Cubs", "Yankees", "Red Sox"); for (teams in playOffs) { trace(playOffs[teams]); }
The teams variable acts as an iterant (that is, it counts iterations through the loop). No matter how short or long, the iterant variable always stops after the last property or element.
The while loop keeps running until a quit condition has been met, using the following format:
while(condition) { //Do something }
For example, the following while loop waits until the end of an array before it stops sending out the array elements:
var counter:Number = 0; var roster:Array = new Array(); roster.push("Tom", "Mary", "Dick", "Suzy", "Harry", "Kim"); while (counter<roster.length) { trace(roster[counter]); counter++; }
A second type of while loop, the do..while loop, places its conditional statement at the end of the loop rather than at the beginning. In a while loop, if the condition to stop the loop is met immediately, none of the statements within the loop are executed. However, a do..while loop executes at least one iteration before stopping, even if the termination condition is immediately satisfied. As you can see in its structure, do..while is clearly different from the while loop:
do { //Do something } while (condition)
For example, the following do..while loop executes the trace statement even though the stop condition is met in the first iteration:
var counter:Number = 0; do { trace("This is an iteration"); } while (counter != 0);
One of the problems you may encounter is an infinite loop. If you make a small mistake in your termination condition, the loop may never be able to exit and will crash Flash.
Conditional
The final basic structure is the conditional statement, which in Flash Pro is fairly standard and comparable to that of conditional statements in other languages.
The simple if statement tests a condition using the following format:
if(condition) { //execute this }
For example, the following looks at a response in an input text field to provide the user with more information about a product by sending him or her to a different URL:
choose_btn.onPress = function() { var checkIt:String = new String(); checkIt = decide_txt.text; checkIt.toLowerCase(); if (checkIt == "yes") { getURL("http://www.sandlight.com", _blank); } };
Forcing a Case
When you're using conditional statements where you have user input, because you have no way of knowing whether the user will use the correct case, changing the input to a single case makes testing the condition easier. Strings can be transformed to all lowercase, as in the previous example, or to uppercase.
A second type of if statement is if..else. This statement has the following format:
if(condition) { //execute this } else { //do something else }
So when you have a single alternative, the else statement is handy. For instance, you could change the previous if code example by adding an else statement to make two options now available, as the following shows:
choose_btn.onPress = function() { var checkIt:String = new String(); checkIt = decide_txt.text; checkIt.toLowerCase(); if (checkIt == "yes") { getURL("http://www.sandlight.com", _blank); } else { getURL("http://www.room99.co.uk", _blank); } };
As a reminder from the "Miscellaneous Operators" section earlier in this chapter, you can use the ternary (?:) operator instead of the if..else statement. Using the ternary operator, the conditional statement from the preceding code would be the following:
checkIt=="yes" ? getURL("http://www.sandlight.com", _blank) : getURL("http://www.room99.co.uk", _blank);
With several different conditions, you will need to use either the else if statement or the switch and case statements. The following script looks to see where the position of a movie clip is and, depending on its location, has different feedback:
moveMe_mc.onPress = function() { this.startDrag(); }; moveMe_mc.onRelease = function() { stopDrag(); }; if (moveMe_mc._x<100) { trace("Move right"); } else if (moveMe_mc._x>300) { trace("Move left"); } else if (moveMe_mc._y<100) { trace("Move down"); } else if (moveMe_mc._y>300) { trace("Move up"); }
Sometimes, rather than using a series of else if statements, you'll want to use the switch/case combination. The general format for the switch/case statement, when employing both the break and default optional statements, is the following:
switch(exp) { case 'state1' : //do something break; case 'state2' : //do something else break; default : //do default }
The following example takes information from an input text field, places it into a String object, and then uses that string ("tool") as the expression within the switch parameter. After each of the case statements is a statement to execute if the case is strictly true in that its contents match that of the switch parameter (strict equality, ===). For example, if the user puts in PHP as a choice, "PHP" is changed to lowercase ("php") by the tool object. If the case strictly equates "php", it gets the appropriate URL and then breaks out of the switch statement using the break statement. If none of the case statements finds a strict equality, the default statement executes.
choose_btn.onPress = function() { var tool:String = new String(); tool = decide_txt.text; tool = tool.toLowerCase(); switch (tool) { case 'flash' : getURL("http://www.macromedia.com"); break; case 'php' : getURL("http://www.php.net"); break; case 'mysql' : getURL("http://www.mysql.org"); break; case 'apache' : getURL("http://www.apache.org"); break; default : trace("No luck"); } };
Although both the else if statement and switch and case statements can generate similar results, the choice of one or the other depends on the nature of the coding problem being solved or the developer's personal preferences.
Functions
The built-in functions in Flash MX Professional 2004 are either in the Global Functions folder or part of the Deprecated folder, both in the Actions toolbox. Those in the latter folder have been replaced by methods in the built-in classes. Therefore, this section will focus on the global functions and the user functions.
Like all functions and methods, the global functions create some action, many of which are unique to Flash. They have been organized into the following folders in the Actions toolbox:
-
Timeline Control
-
Browser/Network
-
Movie Clip Control
-
Printing Functions
-
Miscellaneous Functions
-
Mathematical Functions
-
Conversion Functions
As you use any of these functions, you'll find a good deal of overlap with the methods associated with built-in classes. For example, a global function is gotoAndPlay(). Likewise, you will find that one of the methods associated with the MovieClip object is gotoAndPlay(). As a global function, gotoAndPlay() can be used in just about any script independent of a movie clip. A button script like the following is typical of how a global function would be used:
on(release) { gotoAndPlay(5); }
The same function, used as a MovieClip class instance method, would have to be associated with a specific movie clip. For example, the script
myMovieClip_mc.gotoAndPlay(5);
instructs the movie clip myMovieClip_mc to play Frame 5 on its own Timeline.
Some of the more common global functions include the stop() and play() functions, often found in frame scripts. Subsequent chapters include various uses of these functions, and depending on the context of their use, you should be able to tell whether they're methods or functions.
User-Defined Functions
User-defined functions are used both in a program proper and in the Script Editor in creating classes and their methods. Here's the basic format for creating a user function:
function FunctionName(arguments) { //actions }
The arguments (or parameters) are optional in a function. For example, the following is a perfectly good user function:
checkFuel function() { gotoAndStop("fuel"); if(fuelLevel < 2) { warning=true; } }
The function is invoked by the following simple line:
checkFuel();
By adding an argument to a function definition, you can add a good deal of flexibility to the function. The following function has hor and vert arguments that are used in the function to specify the horizontal and vertical position of a movie clip:
function McPlace(hor, vert) { moveMe_mc._x = hor; moveMe_mc._y = vert; }
To invoke the function, the developer places values in argument positions. For example, the following would place the movie clip at the horizontal position 250 and vertical position 150:
McPlace(250,150);
When functions are used in class definitions, they can become methods of the class. For example, a handy class would be to convert the dollar and cent formatter used with the modulo (%) operator discussed earlier in the section on operators. By casting the sequence as a function inside of a class definition, the function becomes a method of that class. For example, the two files shown in Listings 3.4 and 3.5 are, respectively, an AS file defining the class and a sample FLA file that uses the class to show how the function becomes a method. The function convert() in the class definition is used as the method convert() in the FLA script.
Listing 3.4 A Cent Formatter for Virtually Any Business Use (CentFormat.as)
class CentFormat { function convert(amount:Number) { var dollars:Number = Math.floor(amount); var cents:Number = Math.round(amount*100)%100; var zero:Boolean = cents<10; var zerozero:Boolean = cents == 0; if (zero) { var cents:String = "0"+String(cents); } else if (zerozero) { var cents:String = "00"+String(cents); } return "$"+dollars+"."+cents; } }
Once you save the CentFormat.as file, create a new Flash Pro document with a button (go_btn), an input text field (purchase_txt), and a dynamic text field (output_txt). The instance names are in parentheses.
Listing 3.5 An Easy Way to Format Cents Using the CentFormat Class (functionClass.fla)
var purchase:CentFormat = new CentFormat(); go_btn.onPress = function() { var myPurchase = Number(purchase_txt.text); output_txt.text = purchase.convert(myPurchase); };
After saving the files to the same folder, you can use the convert method with an object created from the CentFormat class. Any value placed in the input text field is reformatted and placed into the output text field when the button is clicked.
Unnamed Functions
A final fundamental feature of ActionScript 2.0 functions can be found in the use of unnamed functions. Throughout the examples, you have seen several unnamed functions. They're very useful when placing object control scripts in frames rather than attaching them directly to the objects themselves. For example, instead of using the button script
on(release) { gotoAndPlay(5); }
you can use an unnamed function to do the same thing:
someButton_btn.onRelease = function() { gotoAndPlay(5); };
A recommended practice is keeping all your scripts in one placeideally in a single frame. By using unnamed (or anonymous) functions, you can address an object anywhere in a document. When it comes time to debug a script, you'll be glad you did.