For instance, continuing the prior example to retrieve the first item in the array mdArray1, you need only the standard single bracket syntax: trace mdArray1[0]; //traces "a" to the Outp
Trang 1a database had three records, it would be equivalent to one array of three
arrays
Creating this arrangement is as simple as using an inner array as a value for
one of the indices of the outer array You can do this at the outset, or add it
using push()—both of which are demonstrated here:
var mdArray1: Array = [ "a" , "b" , [ "c" , "d" ]];
var mdArray2: Array = [ "e" , "f" ];
mdArray2 push ([ "g" , "h" ]);
To access values in a multidimensional array, you must use multiple brackets
to go into the nested arrays For instance, continuing the prior example to
retrieve the first item in the array mdArray1, you need only the standard single
bracket syntax:
trace (mdArray1[0]);
//traces "a" to the Output panel
However, to access the values in the nested array requires two components
index 2) Then you must reference the item within that nested array with
another pair of brackets So, to retrieve “c”, which is the first item in the nested
array, the syntax is as follows:
trace (mdArray1[2][0]);
//traces "c" to the Output panel
This makes sense, if you think about it in steps, because not only is mdArray1
an array requiring bracket syntax to retrieve an item therein, but mdArray1[2]
is also an array requiring its own brackets to retrieve an item
Vectors
Vectors (not to be confused with the precise lines, curves, and shapes created
like those in the previous section can contain data of any type The following
var arr: Array = new Array ();
arr[0] = "avocado" ;
arr[0] = 2;
arr[0] = true ;
A vector, however, can contain data of only one type, which is determined at
the time the vector was created Although vector syntax may look a little odd
at first, its principle uniqueness is the addition of the data type to the vector
creation process The following example vector contains only integers
var vec: Vector < int > = new Vector < int >();
vec[0] = 1;
vec[0] = 2;
vec[0] = 3;
N OT E
There is another kind of array, called
an associative array, which is often used interchangeably with custom objects We’ll discuss both in the “Custom Objects” section later in this chapter.
Trang 2If you try to add an incompatible data type to a vector, you will receive a type
vector from the previous snippet:
vec[3] = "guacamole"
//Error 1067: Implicit coercion of a value of type String // to an unrelated type int.
From a syntax and use perspective, vectors function the same way arrays do Vector syntax is typically identical to array syntax However, because they can contain only one data type, they support more restrictive error checking When working with vectors, you can be certain that any data you retrieve will be the correct data type for your needs, and any data you add will be checked to be sure it conforms to the desired type In addition, vectors can be significantly faster than arrays—particularly with large data sets
Functions
Functions are an indispensable part of programming in that they wrap code into blocks that can be executed only when needed They also allow code blocks to be reused and edited efficiently, without having to copy, paste, and edit repeatedly Without functions, all code would be executed in a linear progression from start to finish, and edits would require changes to every single occurrence of any repeated code We’ll look at functions in three parts: minimal structure, use of arguments, and returning values Figure 2-3 identi-fies examples of each of the parts of a function that we’ll discuss
parameter parameter
data type return data type name
value returned
Figure 2-3. Parts of a function
Creating a basic function requires little more than surrounding the code you wish to trigger at will with a simple syntax that allows you to give the block
of code a name Triggering that function later requires only that you call the function by name
N OT E
One thing to remember about data
type checking when populating vectors
is that content added with the push()
method will be type checked at runtime
For this reason, you should use bracket
syntax when adding elements to a
vec-tor, as in the example in this section,
to receive the benefits of compile-time
error checking
Trang 3The following syntax shows a function that traces a string to the Output
panel The function is first defined and then, to illustrate the process,
imme-diately called (In a real-world scenario, the function is usually called at some
other time or from some other place, such as when the user clicks a button
with the mouse.) The actual output is depicted in the comment that follows
the function call, without any added quotation marks This code can be
function showMsg() {
trace ( "hello" );
}
showMsg();
//hello
If reusing code and executing code only when needed were the only
advan-tages of functions, you’d already have a useful enhancement to the linear
exe-cution of ActionScript, because it would allow you to group your code into
subroutines that could be triggered at any time and in any order However,
you can do much more with functions to gain even greater power
Local Variables
For example, you can define a variable that exists only inside a function
syntax to declare and use the variable is the same; to make it local, simply
declare the variable inside the function These variants on the prior example
function showMsg() {
var msg: String = "hello" ;
trace (msg);
}
showMsg();
//hello
receive an error because ActionScript thinks it doesn’t exist outside the
func-tion The following syntax is what the same example might look like using a
variable that is available to the entire script, not just a single function:
var msg2: String = "hello" ;
function showMsg2() {
trace (msg2);
}
showMsg2();
//hello
this case, tracing msg2 at the end of the script would successfully show “hello”
in the Output panel of Flash Professional
N OT E
Commenting your code to explain as much about what it does as is practical can help you greatly if you return to a project after a prolonged absence It’s also vital to projects with multiple pro-grammers and when distributing your code to others, like clients or the public You can comment a single line of code using two slashes (//), and multiple lines of code using a balanced pair of slash-asterisk (/*) and asterisk-slash (*/).
//single-line comment /*
multi-line comment
*/
N OT E
Unlike some other languages, ActionScript 3.0 does not support block-level local variables That is, declaring a variable within a logical block, such as a conditional or loop, does not confine the life of that variable to the block itself
In ActionScript 3.0, variables are either accessible to an entire script or restricted
to a function, depending on where they’re declared
Trang 4Parameters and Arguments
Even when defining a local variable to hold content, your function is still
“hard-wired.” That is, it can’t change from the effect of some outside influ-ence Let’s say you need to trace ten different messages To do that without any new features, you’d have to create ten functions and vary the string that
is traced inside each function
and arguments—words that are often used interchangeably but that have a subtle distinction Parameters are like local variables in that they exist only inside a function, but they are easier to use because they do not have to be declared Instead, you just place them inside the function’s parentheses and use them inside the function as you see fit Arguments are the values that are passed into those parameters By passing data into a function, you can vary its execution
When using parameters, it is a great idea to use the same data typing prac-tices as you would with variables, so the ActionScript compiler knows how to react and can notify you of errors Simply follow the parameter name with a colon and data type The same rules that apply to naming variables, apply to naming parameters Furthermore, because parameters are local to a function, you can reuse parameter names in different functions without ill effect Just
be sure not to confuse yourself!
In the following example, the function no longer traces “hello” every time it is called Instead, it traces whatever text is sent into the function To send data
in, you need only include the data in the parentheses used when calling the function
function showMsg(msg: String ) { trace (msg);
} showMsg( "goodbye" );
//goodbye You can even use multiple parameters separated by commas and pass mul-tiple arguments to the function To avoid errors, the order of the arguments must match the order of parameters This example expands on the previous code by adding a second parameter In this case, the function uses the plus
function showMsg2(msg: String , user: String ) { trace (msg + ", " + user + "!" );
} showMsg2( "Welcome" , "Sally" );
//Welcome, Sally!
Default values can also be supplied for a parameter This makes sending an argument into the parameter optional because, if no value is sent, the default will be used When using parameter default values, you must place them at the end of the parameter list so they always follow any parameters for which
Trang 5values are required For example, the following code requires a message but
the user name is optional As a result, user must appear after msg in the order
of parameters
function showMsg3(msg: String, user: String = "User" ) {
trace (msg + ", " + user + "!" );
}
showMsg3( "Welcome" , "Claire" );
//Welcome, Claire!
showMsg3( "Welcome" );
//Welcome, User!
Returning a Value from a Function
Finally, it is also possible to return a value from a function, increasing its
usefulness even further Having the ability to return a value to the script
a function
The following examples are used to convert temperature values from Celsius
to Fahrenheit and Fahrenheit to Celsius In both cases, a value is sent into the
function and the result of a calculation is returned to the script The return
value is sent back to the exact same location as the function call
to the right side of an equation, thereby populating a variable This mimics
real-life usage in that you can immediately act upon the returned value or
store and process it at a later time In both cases, the actual trace is shown
function celciusToFarenheit(temp: Number ): Number {
return (9 / 5) * (temp + 32);
}
trace (celciusToFarenheit(20));
//68
function farenheitToCelcius(temp: Number ): Number {
return (5 / 9) * (temp - 32);
}
var temperature: Number = farenheitToCelcius(68);
trace (temperature);
//20
Note that when returning a value from a function, you should also declare
the data type of the return value This is achieved the same way you type data
in variables or parameters—with a colon followed by the data type This time,
the data type is placed between the closing parenthesis of the function’s
dec-laration and its opening curly brace This position symbolizes output, rather
than input, of the function
N OT E
Values are returned from a function immediately, so any code inside the function that appears after the return statement is not executed.
Trang 6Once you get used to this practice, it is best to specify void as a return data
ActionScript compiler that nothing should be returned (by using void as a data type), it can warn you if you inadvertently add a return statement later
Custom Objects
After working with ActionScript for just a short while, you will realize that you are immersed neck-deep in objects—whether you’re using procedural or object-oriented programming In addition to the numerous objects that are already predefined in the ActionScript language (such as movie clips, text fields, sounds, and more), you can create your own objects and give them
properties—the adjectives of the ActionScript world, describing an object’s general characteristics, the way you might describe a movie clip’s width, loca-tion, rotaloca-tion, and so on
To demonstrate this, we’ll create a custom object called villain, and give it properties for health, armor, and lives None of these terms—villain, health, armor, or lives—are already part of the ActionScript language However, the syntax for using custom objects conforms to the same dot syntax used throughout ActionScript, so it will seem like those properties have always been there The following snippet creates an object, and then creates and populates properties:
var villain: Object = new Object() ; villain.health = 100;
villain.armor = 100;
villain.lives = 3;
These values can be called up at any time, by querying the properties the same way they were created
trace (villain.health);
//100
Objects and Associative Arrays
Another way to create a custom object is type its properties and values explic-itly at the time of definition:
var obj: Object = {msg: "Hello" , user: "Jodi" };
syntax to retrieve a key value is the same as described in the prior section Using associative array syntax, you substitute a string of the key, in place of the integer index used with linear arrays Both of the following examples trace
“Hello”:
N OT E
You will use objects later in the book, in
Chapter 10 when working with
cascad-ing style sheets and in Chapter 12 when
working with video.
Trang 7trace (obj.msg);
//associative array syntax
trace (obj[ "msg" ]);
this and parent
Although potentially a bit nebulous when you’re starting with ActionScript,
this can be your friend It is essentially a self-referential pronoun and is
the realm or space within which an object lives For example, think of a movie
clip inside Flash’s main timeline Each of these objects (the movie clip and
main timeline) has a unique scope, so a variable or function defined inside
the movie clip will not exist in the main timeline, and vice versa
It is easiest to understand the usage of this in context, but here are a couple
of examples to get you started If, from the current scope, you wanted to check
the x location of a movie clip with the instance name mc, you might say:
this mc x
Conversely, if you wanted to send the main timeline to frame 2, but do so
from within the movie clip, you might say:
this.parent gotoAndStop (2);
The latter example uses the parent keyword, which refers to the object that
is immediately above the current scope in the object hierarchy In this case, it
refers to a movie clip (or main timeline) in which another movie clip resides,
and this will be discussed a wee bit more in the following section
In both cases, this is a reference point from which you start your path It’s
methods in the current scope Many programmers include the keyword for
clarity, but it’s also sometimes particularly useful or even required—such
as when some ActionScript editors color various parts of your script for
remember that you’re referencing an object—a concept easy to forget if you
frequently omit the friendly pronoun
Absolute Versus Relative Addresses
Much like a computer operating system’s directory, or the file structure of
a website, ActionScript refers to the address of its objects in a hierarchical
fashion You can reference an object address using an absolute or relative
path Absolute paths can be easy because you most likely know the exact
path to any object starting from the top of your application—such as Flash
Professional’s main timeline However, absolute paths are quite rigid and will
N OT E
Depending on how you set up your file, it is often necessary to specifically declare what kind of parent you are ref-erencing For example, you may need to explicitly say the parent is a movie clip before you can work with its timeline
A little more background is probably needed to grasp this, as covered in detail
in the “Clarifying or Changing the Data Type of a Display Object” section of Chapter 4.
Trang 8break if you change the nested relationship of any of the referenced objects Relative paths can be a bit harder to call to mind at any given moment, but they are more flexible Working from a movie clip and going up one level to its parent and down one level to a child will work from anywhere—be that
in the root timeline, another movie clip, or nested even deeper—because the various stages aren’t referenced by name
Tables 2-5 and 2-6 draw analogies to uses found in more familiar computer operating system and website analogies
Table 2-5 Absolute (from main timeline to mc3, a nested movie clip inside mc2)
root.mc2.mc3 c:\folder2\folder3 Macintosh/folder2/folder3 http://www.domain.com/dir/dir
Table 2-6 Relative (from a first-level movie clip called mc1, up to its root, and down to the child of a sibling)
this.parent.mc2.mc3 \folder2\folder3 /folder2/folder3 /dir/dir
Put It All Together
To end this chapter, let’s look at a script that brings together much of what we’ve discussed to create a randomizing sentence builder This code can be
a series of arrays of adjectives, nouns, and verbs, imagined by my children, Sally and Claire
Lines 9 through 22 define the buildASentence() function, which takes the adjective, noun, and verb arrays as arguments Lines 10 through 12 store the number of items in each array, and then the conditional in lines 13 through 15 check to make sure there is at least one item in each array If any array has 0 items, a warning is returned in line 14 and the function is at an end
random() method generates a random number between 0 and 1, which is then
multiplied by the length of each array The resulting numbers will be used in line 21 as indices to retrieve values from the arrays that were passed into the function Because array indices must be integers, we must round the random number created
However, a random number between 0 and 3 might round to a value of 3 Traditional rounding techniques round up when the number is 0.5 or above, and round down for anything under 0.5 So, value of 2.9 would round up to
3 In this case, you’d receive an error because only items 0, 1, and 2 exist in the array There is no fourth item (that would be retrieved with an index of 3)
Trang 9To skirt this possibility, we force the rounding operation to round down,
using the Math.floor() method, allowing only numbers 0, 1, and 2
The function then ends by returning a sentence It combines “The ”, a
ran-dom adjective, a space, a ranran-dom noun, a space, a ranran-dom verb, and “ away!”
and returns it to the caller of the function We’ll look at that process, after
the code
1 var adjsSally: Array = [ "hairy" , "funny" , "bouncy" ];
2 var nounsSally: Array = [ "daddy" , "mommy" , "sister" ];
3 var verbsSally: Array = [ "drove" , "swam" , "ran" ];
4
5 var adjsClaire: Array = [ "tall" , "snuggly" , "clean" ];
6 var nounsClaire: Array = [ "duck" , "birdy" , "chipmunk" ];
7 var verbsClaire: Array = [ "ran" , "jumped" , "tip-toed" ];
8
9 function buildASentence(adj: Array , noun: Array , verb: Array ): String {
10 var aCount: int = adj length ;
11 var nCount: int = noun length ;
12 var vCount: int = verb length ;
13 if (aCount == 0 || nCount == 0 || vCount == 0) {
14 return ( "not enough words provided" );
15 }
16
17 var a: int = Math.floor ( Math.random () * aCount);
18 var n: int = Math.floor ( Math.random () * nCount);
19 var v: int = Math.floor ( Math.random () * vCount);
20
21 return "The " + adj[a] + " " + noun[n] + " " + verb[v] +
"away!" ;
22 }
23
24 for ( var i: int = 0; i < 3; i++) {
25 var sallySays: String = makeASentence(adjsSally, nounsSally,
verbsSally);
26 trace (sallySays);
27
28 var claireSays: String = makeASentence(adjsClaire, nounsClaire,
verbsClaire);
29 trace (claireSays);
30 }
executes 3 times, calling the function with Sally’s arrays (line 25) and Claire’s
arrays (line 28) The function returns a sentence in each line, and the loop
then traces the results in lines 26 and 29 The results are random, but here
is a sample:
The funny mommy drove away!
The snuggly birdy ran away!
The funny sister swam away!
The tall duck tip-toed away!
The hairy daddy swam away!
The clean chipmunk jumped away!
N OT E
Here are some examples of the round-ing features of the Math class, with the results listed as comments following each method:
Math.round (0.8); //1 Math.round (0.2); //0 Math.floor (0.8); //0 Math.floor (0.2); //0 Math.ceil (0.8); //1 Math.ceil (0.2); //1
The Math.round() method rounds
up when the value is 0.5 and above and down when the value is below 0.5
Math.floor() always rounds down, and Math.ceil() (short for ceiling) always rounds up to the nearest whole number
Trang 10What’s Next?
Ideally, we’ve provided just enough background (or review) of key ActionScript fundamentals to now focus on topical syntax Although we won’t entirely ignore basic elements within the scripts of future chapters, we will spend more time describing the collective goal of a script, and highlighting new issues introduced or updated by ActionScript 3.0
Next, we start off the ActionScript 3.0-specific material with a look at the three essential building blocks of most ActionScript objects: properties, methods, and events Events are one of the most significantly changed ele-ments of ActionScript with the introduction of version 3.0
In the next chapter, we’ll discuss:
• The descriptive properties, such as width, height, location, alpha (opaci-ty), rotation, and more, of each object that define its major characteristics
• The actions you may exert on objects, or that objects may take on other objects, in the form of methods
• The events issued by the user or aspects of your program or environment