ActionScript Basics: Chapter 1 - ActionScript 3.0 Cookbook
Pages: 1, 2, 3, 4

Section 1.7: Using Mathematical Operators

Problem

You want to modify something over time, such as the rotation or position of a sprite.

Solution

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.

Discussion

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.

These statements both add 6 to the existing value of quantity:

quantity = quantity + 6;
quantity += 6;

These statements both subtract 6 from the existing value of quantity:

quantity = quantity - 6;
quantity -= 6;

These statements both multiple quantity by factor:

quantity = quantity * factor;
quantity *= factor;

These statements both divide quantity by factor:

quantity = quantity / factor;
quantity /= factor;

There should be no space between the two symbols that make up a compound assignment operator. Additionally, if you are incrementing or decrementing a variable by 1, you can use the increment or decrement operators.

This statement adds 1 to quantity:

quantity++;

and has the same effect as either of these statements:

quantity = quantity + 1;
quantity += 1;

This statement subtracts 1 from quantity:

quantity --;

and has the same effect as either of these statements:

quantity = quantity - 1;
quantity -= 1;

You can use the increment and decrement operators ( -- and ++) either before or after the variable or property they operate upon. If used before the operand, they are called prefix operators. If used after the operand, they are called postfix operators. The prefix and postfix operators modify the operand in the same way but at different times. In some circumstances, there is no net difference in their operation, but the distinction is still important in many cases. When using prefix operators, the value is modified before the remainder of the statement or expression is evaluated. And if you're using postfix operators, the value is modified after the remainder of the statement has executed. Note how the first example increments quantity after displaying its value, whereas the second example increments quantity before displaying its value:

var quantity:Number = 5;
trace(quantity++);  // Displays: 5
trace(quantity);    // Displays: 6

var quantity:Number = 5;
trace(++quantity);  // Displays: 6
trace(quantity);    // Displays: 6

Getting back to the original problem, you can use these operators to modify a property over time. This example causes the specified sprite to rotate by five degrees each time the method is called:

private function onEnterFrame(event:Event) {
  _sprite.rotation += 5;
}

Note that in ActionScript 3.0, you would have to add an event listener to the enterFrame event and set this method as the event handler for this to work properly. See Recipe 1.5 for information on how to handle the enterFrame event.

See Also

Recipe 1.5

Section 1.8: Checking Equality or Comparing Values

Problem

You want to check if two values are equal.

Solution

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( ).

Discussion

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 a strict flag, 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 the strict flag, 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 (!=) returns false if two values are equal and true if 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 if strict type checking is disabled.

On the other hand, if you have turned off the strict flag, but you want to perform a strict comparison in one section of code, you can use the strict equality and inequality operators, === and !==. These first check whether the values being compared are of the same datatype before performing the comparison. Differences in datatypes causes the strict equality operator to return false and the strict inequality operator to return true:

trace(6 === 6);    // Displays: true
trace(6 === "6");  // Displays: false
trace(6 !== 6);    // Displays: false
trace(6 !== "6");  // Displays: true

There is a big difference between the assignment operator (=) and the equality operator (==). If you use the assignment operator instead of the equality operator, the variable's value will change rather than testing its current value.

Using the wrong operator leads to unexpected results. In the following example, quantity equals 5 at first, so you might expect the subsequent if statement to always evaluate to false, preventing the trace( ) from being executed:

var quantity:int = 5;
// The following code is wrong. It should be if (quantity == 6) instead
if (quantity = 6) {
  trace("Rabbits are bunnies.");
}
trace("quantity is " + quantity);  // Displays: quantity is 6

However, the example mistakenly uses the assignment operator (=) instead of the equality operator (==). That is, the expression quantity = 6 sets quantity to 6 instead of testing whether quantity is 6. When used in an if clause, the expression quantity = 6 is treated as the number 6. Because, any nonzero number used in a test expression converts to the Boolean true, the trace( ) action is called. Replace the test expression with quantity == 6 instead. Fortunately, the ActionScript 3.0 compiler is smart enough to recognize this common error and although the code still compiles, you aren't given a warning.

You can check an item's datatype using the is operator, as follows:

var quantity:int = 5;
if (quantity is int) {
  trace("Yippee. It's an integer.");
}

Note that the new ActionScript 3.0 types int and uint will also test positive as Numbers.

However, some numeric values are invalid. The following example results in quantity being set equal to NaN (a constant representing invalid numbers, short for not a number) because the calculation cannot be performed in a meaningful way:

var quantity:Number = 15 - "rabbits";

Despite its name, NaN is a recognized value of the Number datatype:

trace(typeof quantity);   // Displays: "number"

Therefore, to test if something is not just any number, but a valid number, try this:

var quantity:Number = 15 - "rabbits";
if (quantity is Number) {

  // Nice try, but this won't work
  if (quantity != NaN) {
    trace("Yippee. It's a number.");
  }
} 

However, you can't simply compare a value to the constant NaN to check whether it is a valid number. The ActionScript 3.0 compiler even gives you a warning to this effect. Instead, you must use the special isNaN( ) function to perform the test.

To determine if a number is invalid, use the special isNaN( ) function, as follows:

var quantity:Number = 15 - "rabbits";
if (isNaN(quantity)) {
  trace("Sorry, that is not a valid number.");
}

To test the opposite of a condition (i.e., whether a condition is not true) use the logical NOT operator (!). For example, to check whether a variable contains a valid number, use !isNAN( ), as follows:

var quantity:Number = 15 - "rabbits";
if (!isNaN(quantity)) {

  // The number is not invalid, so it must be a valid number
  trace ("That is a valid number.");
}

Of course, you can perform comparisons using the well-known comparison operators. For example, you can use the < and > operators to check if one value is less than or greater than another value:

trace(5 < 6);    // Displays: true
trace(5 > 5);    // Displays: false

Similarly, you can use the <= and >= operators to check if one value is less than or equal to, or greater than or equal to, another value:

trace(5 <= 6);   // Displays: true
trace(5 >= 5);   // Displays: true

You should also be aware that ActionScript compares datatypes differently. ActionScript datatypes can be categorized either as primitive (string, number, and Boolean) or composite (object, sprite, and array). When you compare primitive datatypes, ActionScript compares them "by value." In this example, quantity and total are considered equal because they both contain the value 6:

var quantity:Number = 6;
var total:Number = 6;
trace (quantity == total);         // Displays: true

However, when you compare composite datatypes, ActionScript compares them "by reference." Comparing items by reference means that the two items are considered equal only if both point to exactly the same object, not merely objects with matching contents. For example, two arrays containing exactly the same values are not considered equal:

// Create two arrays with the same elements.
var arrayOne:Array = new Array("a", "b", "c");
var arrayTwo:Array = new Array("a", "b", "c");
trace(arrayOne == arrayTwo);          // Displays: false

Two composite items are equal only if they both refer to the identical object, array, or sprite. For example:

// Create a single array
var arrayOne:Array = new Array("a", "b", "c");
// Create another variable that references the same array.
var arrayTwo:Array = arrayOne;
trace(arrayOne == arrayTwo);          // Displays: true

See Also

Recipe 5.8

Section 1.9: Performing Actions Conditionally

Problem

You want to perform some action only when a condition is true.

Solution

Use an if or a switch statement.

Discussion

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 is true). 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 keyword if followed 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 whether animalName contains the word "turtle." This might be used to check whether the user answered a quiz question correctly (here, animalName is 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 (=), which is used to assign a value to an item.

if (animalName == "turtle") {
  // This trace( ) statement executes only when animalName is equal 
  // to "turtle".
  trace("Yay! 'Turtle' is the correct answer.");
}

Additionally, you can add an else clause to an if statement to perform alternative actions if the condition is false. Note that for the trace( ) command to have any effect, the .swf must be compiled using Debug, and not Run, mode. Make a call to a method named showMessage( ) that displays an appropriate message depending on whether the user got the answer right or wrong:

if (animalName == "turtle") {
  // These statements execute only when animalName is equal 
  // to "turtle".
  showMessage("Yay! 'Turtle' is the correct answer.");
}
else {
  // These statements execute only when animalName is not equal 
  // to "turtle".
  showMessage("Sorry, you got the question wrong.");  
}

For testing purposes, you can create a showMessage( ) method that traces out the string sent to it. In a real-world example, you might want to display this message in a text field, or display it to the user some other way, such as in a dialog box.

You can add an else if clause to an if statement. If the if condition is true, the else if clause is skipped. If the if condition is false, the ActionScript interpreter checks to see if the else if condition is true:

if (animalName == "turtle") {
  // This trace( ) statement executes only when animalName is equal 
  // to "turtle".
  showMessage ("Yay! 'Turtle' is the correct answer.");
}
else if (animalName == "dove") {
  // This trace( ) statement executes only when animalName is not 
  // "turtle", but is "dove".
  showMessage ("Sorry, a dove is a bird, not a reptile.");
}

What if the preceding example was written as two separate if statements (one to check if animalName is "turtle" and another to check if it is "dove")? The example would work as intended, but it would be less efficient. Using the else if statement guarantees that if animalName is "turtle"; we don't bother checking if it is also equal to "dove."

If your two conditions are mutually exclusive, use an else if clause to check the second condition. If your two conditions are not mutually exclusive, and you want to perform both statement blocks when both conditions are met, use two separate if statements.

When you use an if statement with both else if and else clauses, the else clause must be the last clause in the statement. The final else clause is convenient as a catchall; it's where you can put statements that take the appropriate action if none of the other conditions are met.

if (animalName == "turtle") {
  // This trace( ) statement executes only when animalName is equal 
  // to "turtle".
  showMessage ("Yay! 'Turtle' is the correct answer.");
}
else if (animalName == "dove") {
   // This statement executes only when animalName is not 
   // "turtle", but is "dove".
  showMessage ("Sorry, a dove is a bird, not a reptile.");
}
else {
  // This statement executes only when animalName is neither 
  // "turtle" nor "dove".
  showMessage ("Sorry, try again.");
}

You can also include more than one else if clause in an if statement. However, in that case, you should most likely use a switch statement instead; generally, switch statements are more legible and succinct than the comparable if statement. Where performance is critical, some ActionScripters prefer to use if statements, which allow somewhat greater control for optimization purposes.

A switch statement is composed of three parts:

The switch keyword
Every switch statement must begin with the switch keyword.
Test expression
An expression, enclosed in parentheses, whose value you want to test to determine which action or actions to execute.
The switch statement body
The statement body, enclosed in curly braces, is composed of cases. Each case is made up of the following parts:
The case or default keyword
A case must begin with a case keyword. The exception is the default case (analogous to an else clause in an if statement), which uses the default keyword.
Case expression
An expression, whose value is to be compared to the switch statement's test expression. If the two values are equal, the code in the case body is executed. The default case (the case that uses the default keyword) does not need a case expression.
Case body
One or more statements, usually ending in a break statement, to be performed if that case is true.

The switch keyword is always followed by the test expression in parentheses. Then the switch statement body is enclosed in curly braces. There can be one or more case statements within the switch statement body. Each case (other than the default case) starts with the case keyword followed by the case expression and a colon. The default case (if one is included) starts with the default keyword followed by a colon. Therefore, the general form of a switch statement is:

switch (testExpression) {
  case caseExpression:
    // case body
  case caseExpression:
    // case body
  default:
    // case body
}

Note that once a case tests true, all the remaining actions in all subsequent cases within the switch statement body also execute. This example is most likely not what the programmer intended.

Here is an example:

var animalName:String = "dove";

/* In the following switch statement, the first trace( ) statement 
   does not execute because animalName is not equal to "turtle". 
   But both the second and third trace( ) statements execute, 
   because once the "dove" case tests true, all subsequent code 
   is executed.
*/
switch (animalName) {
  case "turtle":
    trace("Yay! 'Turtle' is the correct answer.");
  case "dove":
    trace("Sorry, a dove is a bird, not a reptile.");
  default:
    trace("Sorry, try again.");
}

Normally, you should use break statements at the end of each case body to exit the switch statement after executing the actions under the matching case.

The break statement terminates the current switch statement, preventing statements in subsequent case bodies from being erroneously executed.

You don't need to add a break statement to the end of the last case or default clause, since it is the end of the switch statement anyway.

var animalName:String = "dove";

// Now, only the second trace( ) statement executes.
switch (animalName) {
  case "turtle":
    trace("Yay! 'Turtle' is the correct answer.");
    break;
  case "dove":
    trace("Sorry, a dove is a bird, not a reptile.");
    break;
  default:
    trace("Sorry, try again.");
}

The switch statement is especially useful when you want to perform the same action for one of several matching possibilities. Simply list multiple case expressions one after the other. For example:

switch (animalName) {
  case "turtle":
  case "alligator":
  case "iguana":
    trace("Yay! You named a reptile.");
    break;
  case "dove":
  case "pigeon":
  case "cardinal":
    trace("Sorry, you specified a bird, not a reptile.");
    break;
  default:
    trace("Sorry, try again.");
}

ActionScript also supports the ternary conditional operator (? :), which allows you to perform a conditional test and an assignment statement on a single line. A ternary operator requires three operands, as opposed to the one or two operands required by unary and binary operators. The first operand of the conditional operator is a conditional expression that evaluates to either true or false. The second operand is the value to assign to the variable if the condition is true, and the third operand is the value to assign if the condition is false.

               varName = (conditional expression) ? valueIfTrue : valueIfFalse;

Section 1.10: Performing Complex Conditional Testing

Problem

You want to make a decision based on multiple conditions.

Solution

Use the logical AND (&&), OR (||), and NOT (!) operators to create compound conditional statements.

Discussion

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 is false instead of true:

// Check to see if a sprite is invisible (not visible). If so, 
// display a message. This condition is shorthand for 
// _sprite.visible != true or _sprite.visible == false.
if (!_sprite.visible) {
  trace("The sprite is invisible. Set it to visible before trying this action.");
}

The logical NOT operator is often used in compound conditions along with the logical OR operator:

// Check to see if the name is neither Bruce nor Joey. (This could
// also be rewritten using two inequality operators and a logical
// AND.)
if (!((userName == "Bruce") || (userName == "Joey"))) {
  trace ("Sorry, but only Bruce and Joey have access to this application.");
}

ActionScript doesn't bother to evaluate the second half of a logical AND statement unless the first half of the expression is true. If the first half is false, the overall expression is always false, so it would be inefficient to bother evaluating the second half. Likewise, ActionScript does not bother to evaluate the second half of a logical OR statement unless the first half of the expression is false. If the first half is true, the overall expression is always true .

Section 1.11: Repeating an Operation Many Times

Problem

You want to perform some task multiple times within a single frame.

Solution

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);
}

Discussion

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.

Pages: 1, 2, 3, 4

Next Pagearrow