ActionScript Basics: Chapter 1 - ActionScript 3.0 Cookbook

by Joey Lott, Darron Schall, Keith Peters

This excerpt is from ActionScript 3.0 Cookbook. Well before Ajax and Windows Presentation Foundation, Macromedia Flash provided the first method for building "rich" web pages. Now, Adobe is making Flash a full-fledged development environment, and learning ActionScript 3.0 is key. That's a challenge for even the most experienced Flash developer. This Cookbook offers more than 300 solutions to solve a wide range of coding dilemmas, so you can learn to work with the new version right away.

buy button

Section 1.0: Introduction

Using ActionScript, you can create Flash applications that do just about anything you can imagine. But before launching into the vast possibilities, let's start with the basic foundation. The good news is that ActionScript commands follow a well-defined pattern, sharing similar syntax, structure, and concepts. Mastering the fundamental grammar puts you well on the way to mastering ActionScript.

This chapter addresses the frequent tasks and problems that relate to core ActionScript knowledge. Whether you are a beginner or master--or somewhere in between--these recipes help you handle situations that arise in every ActionScript project.

This book assumes that you have obtained a copy of Flex Builder 2 and have successfully installed it on your computer. It's also helpful if you have some experience using a previous version of ActionScript as well.

When you launch Flex Builder 2, the Eclipse IDE should start up and present you with a welcome screen. You are presented with various options to get started and more information about Flex and ActionScript 3, such as links to documentation, tutorials, and more. You can close that screen by clicking on the small "x" on its tab. Now you are in the Eclipse IDE itself, ready to start coding; but where do you go from here?

Flex Builder 2 allows you to create three kinds of projects: a Flex project, Flex Library project, and an ActionScript project. The difference is that Flex projects have access to the entire Flex Framework, which includes all of the Flex components, layout management, transitions, styles, themes, data binding, and all the other stuff that goes into making a Flex Rich Internet Application. Flex applications are written in MXML (a form of XML), which describes the layout and relationship between components. They use ActionScript for their business logic. Although you can use the ActionScript knowledge you learn from here in Flex applications you write, this book concentrates on ActionScript projects exclusively.

Now, if you are familiar with Flash 8 or earlier versions of the Flash IDE, you may be a bit baffled the first time you open up Flex Builder 2. There is no timeline, no library, no drawing tools or color pickers. You'll be doing pretty much everything by code alone, which is why it is called an ActionScript project, rather than a Flash project. So we'll first cover how to create a project and then to get you started with entering your first ActionScript statements.

Section 1.1: Creating an ActionScript Project

Problem

You've launched Flex Builder 2 and want to create an ActionScript project.

Solution

Use the New ActionScript Project Wizard to set up your project.

Discussion

An ActionScript project usually consists of at least one class file and a folder named bin that contains the SWF and HTML files output by the compiler. It also consists of a lot of internal settings to let the compiler know where everything is and how to compile it all. Flex Builder 2 takes care of most of this for you when you use the New ActionScript Project Wizard. There are a few ways to start this wizard. You can use the menu FilenScript Project from the list of available projects there. You can also click the small arrow next to the New button, which gives you the same list.

Whichever route you take to get there, you should wind up with the New ActionScript Project Wizard. Here you'll be prompted to type in a name for your project, such as ExampleApplication. Once you've created the project, you'll notice that the main application file is automatically set to the same name as the project name, with a .as extension.

Clicking the Next button gives you the opportunity to set custom class paths, additional libraries, and specify your output folder to something than the default bin. For now, you don't need to do anything here, so just press Finish to exit the wizard.

Flex Builder 2 now creates the necessary folders and files and applies all the default compiler settings for your project. In the Navigator view, you should now see a ExampleApplication project, which contains an empty bin folder and a ExampleApplication.as class file. Note that it has created this main class file for you automatically and has opened it up for editing in the code view. Also, in the Outline view, you can see a tree representation of the class, including its methods, properties, and any import statements.

To run your new application, you can press one of two buttons in the toolbar. One has a bug-like icon, which when pressed debugs the application, meaning it includes some extra information for debugging purposes and allows the use of trace statements. The button next to it--a circle with an arrow--runs the application. Both actions will create a .swf file and an HTML file, and then launch the HTML file in your default browser.

Of course, at this point, you haven't added anything to the application, so it is the equivalent of testing a blank .fla file in the Flash IDE. But go ahead and do so just to verify that everything is set up properly. You should get an empty web page with a blue background.

Section 1.2: Customizing the Properties of an Application

Problem

You want to change the dimensions of the output .swf, or its background color, frame rate, etc.

Solution

Specify properties as ActionScript Compiler arguments or metadata in the class file.

Discussion

Unlike earlier versions of Flash, the ActionScript 3.0 compiler is actually a command-line compiler. Technically, you could create all your classes and directories and run the compiler from the command line with a long chain of parameters. However, it's much easier to let Eclipse keep track of all those parameters, add all of them, and run the compiler when you tell it to run.

When you create a new ActionScript project, it sets up default parameters that result in an 500 Next, choose ActionScript Compiler from the list on the left. This allows you to change several aspects of how the compiler does its job. Look for the text field labeled "Additional compiler arguments." Anything you type in this text field is passed directly to the command-line compiler as an argument.

Here are the most common arguments you will probably be using:

-default-size width height

-default-background-color color

-default-frame-rate fps
            

You enter them exactly as presented, with numbers for arguments, like so:

-default-size 800 600

-default-background-color 0xffffff

-default-frame-rate 31

The first example sets the resulting size of the resulting .swf to 800x600 pixels. The second sets its background to white, and the last sets its frame rate to 31 fps. Multiple arguments would just be placed one after the other on the same line, like so:

-default-size 800 600 -default-frame-rate 31

Check the Flex Builder 2 help files for mxmlc options to see the full list of command-line arguments you can enter here.

The second way to change these properties is through metadata in your main class file. Metadata consists of any statements that are not directly interpreted as ActionScript, but which the compiler uses to determine how to compile the final output files. The metadata statement that is equivalent to the previous example looks like this:

[SWF(width="800", height="600", backgroundColor="#ffffff", frameRate="31")]

This line is placed inside the main package block, but outside any class definitions (usually just before or after any import statements).

Section 1.3: Where to Place ActionScript Code

Problem

You have a new ActionScript project and need to know where to put the code for it to execute properly.

Solution

Place ActionScript code in the constructor and additional methods of the class.

Discussion

In ActionScript 1.0 and 2.0, you had many choices as to where to place your code: on the timeline, on buttons and movie clips, on the timeline of movie clips, in external .as files referenced with #include, or as external class files. ActionScript 3.0 is completely class-based, so all code must be placed in methods of your project's classes.

When you create a new ActionScript project, the main class is automatically created, and opened in the Code view. It should look something like this:

        package {
             import flass.display.Sprite;
             
             public class ExampleApplication extends Sprite
             {
                 public function ExampleApplication()
                 {
                 
                 }
             }
        }

Even if you are familiar with classes in ActionScript 2.0, there are some new things here. There is a lot more information on this subject in Chapter 2, but let's go through the basics here.

The first thing you'll notice is the word package at the top of the code listing. Packages are used to group classes of associated functionality together in ActionScript 2.0, packages were inferred through the directory structure used to hold the class files. In ActionScript 3.0, however, you must explicitly specify packages. For example, you could have a package of utility classes. This would be declared like so:

package com.as3cb.utils {

}

If you don't specify a package name, your class is created in the default, top-level package. You should still include the package keyword and braces.

Next, place any import statements. Importing a class makes that class available to the code in the file and sets up a shortcut so you don't have to type the full package name every time you want to refer to that class. For example, you can use the following import statement:

import com.as3cb.utils.StringUtils;

Thereafter you can refer to the StringUtils class directly without typing the rest of the path. As shown in the earlier example, you will need to import the Sprite class from the flash.display package, as the default class extends the Sprite class.

Next up is the main class, ExampleApplication. You might notice the keyword public in front of the class definition. Although you can't have private classes within a package, you should label the class public. Note that the main class extends Sprite. Also, a .swf itself is a type of sprite or movie clip, which is why you can load a .swf into another .swf and largely treat it as if it were just another nested sprite or movie clip. This main class represents the .swf as a whole, so it should extend the Sprite class or any class that extends the Sprite class (such as MovieClip).

Finally, there is a public function (or method, in class terminology) with the same name as the class itself. This makes it a constructor. A class's constructor is automatically run as soon as an instance of the class is created. In this case, it is executed as soon as the .swf is loaded into the Flash player. So where do you put your code to get it to execute? Generally, you start out by putting some code in the constructor method. Here's a very simple example that just draws a bunch of random lines to the screen:

package {
    import flash.display.Sprite;
    public class ExampleApplication extends Sprite {
        public function ExampleApplication( ) {
            graphics.lineStyle(1, 0, 1);
            for(var i:int=0;i<100;i++) {
                graphics.lineTo(Math.random( ) * 400, Math.random( ) * 400);
            }
        }
    }
}

Save and run the application. Your browser should open the resulting HTML file and display the .swf with 100 random lines in it. As you can see, the constructor was executed as soon as the file was loaded into the player.

In practice, you usually want to keep code in the constructor to a bare minimum. Ideally the constructor would just contain a call to another method that initializes the application. See Recipes 1.13 and 1.14 for more on methods.

For beginners, now that you know where to enter code, here is quick primer on terminology. These definitions are briefly stated and intended to orient people who have never programmed before. For more complete definitions, refer to the Flash help files.

Variables
Variables are convenient placeholders for data in your code, and you can name them anything you'd like, provided the name isn't already reserved by ActionScript and the name starts with a letter, underscore, or dollar sign (but not a number). The help files installed with Flex Builder 2 contain a list of reserved words. Variables are convenient for holding interim information, such as a sum of numbers, or to refer to something, such as a text field or sprite. Variables are declared with the var keyword the first time they are used in a script. You can assign a value to a variable using an equal sign (=), which is also known as the assignment operator. If a variable is declared outside a class method, it is a class variable. Class variables, or properties, can have access modifiers, public, private, protected, or internal. A private variable can only be accessed from within the class itself, whereas public variables can be accessed by objects of another class. Protected variables can be accessed from an instance of the class or an instance of any subclass, and internal variables can be accessed by any class within the same package. If no access modifier is specified, it defaults to internal.
Functions
Functions are blocks of code that do something. You can call or invoke a function (that is, execute it) by using its name. When a function is part of a class, it is referred to as a method of the class. Methods can use all the same modifiers as properties.
Scope
A variable's scope describes when and where the variable can be manipulated by the code in a movie. Scope defines a variable's life span and its accessibility to other blocks of code in a script. Scope determines how long a variable exists and from where in the code you can set or retrieve the variable's value. A function's scope determines where and when the function is accessible to other blocks of code. Recipe 1.13 deals with issues of scope.
Event handler
A handler is a function or method that is executed in response to some event such as a mouseclick, a keystroke, or the movement of the playhead in the timeline.
Objects and classes
An object is something you can manipulate programmatically in ActionScript, such as a sprite. There are other types of objects, such as those used to manipulate colors, dates, and text fields. Objects are instances of classes, which means that a class is a template for creating objects and an object is a particular instance of that class. If you get confused, think of it in biological terms: you can consider yourself an object (instance) that belongs to the general class known as humans.
Methods
A method is a function associated with an object that operates on the object. For example, a text field object's replaceSelectedText( ) method can be used to replace the selected text in the field.
Properties
A property is an attribute of an object, which can be read and/or set. For example, a sprite's horizontal location is specified by its x property, which can be both tested and set. On the other hand, a text field's length property, which indicates the number of characters in the field, can be tested but cannot be set directly (it can be affected indirectly, however, by adding or removing text from the field).
Statements
ActionScript commands are entered as a series of one or more statements. A statement might tell the playhead to jump to a particular frame, or it might change the size of a sprite. Most ActionScript statements are terminated with a semicolon (;). This book uses the terms statement and action interchangeably.
Comments
Comments are notes within code that are intended for other humans and ignored by Flash. In ActionScript, single-line comments begin with // and terminate automatically at the end of the current line. Multiline comments begin with /* and are terminated with */.
Interpreter
The ActionScript interpreter is that portion of the Flash Player that examines your code and attempts to understand and execute it. Following ActionScript's strict rules of grammar ensures that the interpreter can easily understand your code. If the interpreter encounters an error, it often fails silently, simply refusing to execute the code rather than generating a specific error message.

Don't worry if you don't understand all the specifics. You can use each recipe's solution without understanding the technical details, and this primer should help you understand the terminology.

See Also

Recipes 1.13 and 1.14

Section 1.4: How to Trace a Message

Problem

You need to trace out a message or the value of some data at runtime.

Solution

Use the trace function, pass the data to it, run your application, and look for a message in the Console in Eclipse.

Discussion

You can trace out a message, the value of a variable, or just about any other data using trace, just as you would in earlier versions of ActionScript. Some examples:

trace("Hello, world");

trace(userName);

trace("My name is " + userName + ".");

Since the .swf is now launched in an external browser, it might seem that there is no way to capture the output of these trace statements. Fortunately, it is possible, and this functionality has been built in to Flex Builder 2 via the Console view. The Console view is the equivalent of the Output panel in the Flash IDE. Although it is not open when you first start Eclipse, it appears when needed.

The only requirement to using trace and the Console view is that you use Debug to test your application. Doing so includes extra features in the .swf that allows it to communicate back to the Console behind the scenes and pass any messages you trace. The following class creates a variable, assigns a value to it, and then traces it, along with some other string data:

package {
    import flash.display.Sprite;
    
    public class ExampleApplication extends Sprite {
        public function ExampleApplication( ) {
            var userName:String = "Bill Smith";
            trace("My name is " + userName + ".");
        }
    }
}

Now when you debug your application, it launches as usual in your default browser. Close the browser and switch back to Eclipse. You will see that the Console view is now open and has displayed the data you traced out.

When you launch the debug version of an application, you must have the debug version of Flash Player installed. If you don't have the debug version of Flash Player, you'll see an error message notifying you, and you'll have to download and install it from http://www.adobe.com/support/flashplayer/downloads.html.

Additionally, the debug version of Flash Player can write trace content to a file. The file that Flash Player uses is determined by mm.cfg, a file that is stored in the following locations:

Operating systemLocation
Windows XPC:\\Documents and Settings\\[user name]\\mm.cfg
Windows 2000C:\\mm.cfg
Mac OS XMacHD:Library:Application Support:macromedia:mm.cfg

The mm.cfg file allows you to set the following variables:

TraceOutputFileEnable
The value can be 0 (don't write trace content to a file) or 1 (write to a file).
TraceOutputFileName
The path to the file to which to write. If a value isn't specified, then the content is written to flashlog.txt in the same directory as mm.cfg.
ErrorReportingEnable
The value can be 0 (don't write errors to the logfile) or 1 (write errors to the logfile). The default value is 0.
MaxWarnings
The maximum number of errors to write to the logfile. If this value is set to 0, there is no limit. If a larger value is specified, that limit is imposed and any errors beyond the limit are not written to the log.

At a minimum mm.cfg must contain the following enable writing to a file.

TraceOutputFileEnable=1

If you want to specify more than one variable, you should place each on a new line, as follows

TraceOutputFileEnable=1
TraceOutputFileName=C:\\flex.log

Section 1.5: Handling Events

Problem

You want to have some code repeatedly execute.

Solution

Add a listener to the enterFrame event and assign a method as a handler.

Discussion

In ActionScript 2.0 handling the enterFrame event was quite simple. You just had to create a timeline function called onEnterFrame and it was automatically called each time a new frame began. In ActionScript 3.0, you have much more control over the various events in a .swf, but a little more work is required to access them.

If you are familiar with the EventDispatcher class from ActionScript 2.0, you should be right at home with ActionScript 3.0's method of handling events. In fact, EventDispatcher has graduated from being an externally defined class to being the base class for all interactive objects, such as sprites.

To respond to the enterFrame event, you have to tell your application to listen for that event and specify which method you want to be called when the event occurs. This is done with the addEventListener method, which is defined as follows:

addEventListener(type:String, listener:Function)

There are additional parameters you can look up in the help files, but this is the minimum implementation.

The type parameter is the type of event you want to listen to. In this case, it would be the string, "enterFrame". However, using string literals like that opens your code to errors that the compiler cannot catch. If you accidentally typed "enterFrane", for example, your application would simply listen for an "enterFrane" event. To guard against this, it is recommended that you use the static properties of the Event class. You should already have the Event class imported, so you can call the addEventListener method as follows:

addEventListener(Event.ENTER_FRAME, onEnterFrame);

Now if you accidentally typed Event.ENTER_FRANE, the compiler would complain that such a property did not exist.

The second parameter, onEnterFrame, refers to another method in the class. Note, that in ActionScript 3.0, there is no requirement that this method be named onEnterFrame. However, naming event handling methods on plus the event name is a common convention. This method gets passed an instance of the Event class when it is called. Therefore, you'll need to import that class and define the method so it accepts an event object:

import flash.events.Event;

private function onEnterFrame(event:Event) {

}

The event object contains information regarding the event that may be useful in handling it. Even if you don't use it, you should still set your handler up to accept it. If you are familiar with the ActionScript 2.0 version of EventDispatcher, you'll see a difference in implementation here. In the earlier version, there was an issue with the scope of the function used to handle the event, which often required the use of the Delegate class to correct. In ActionScript 3.0, the scope of the handling method remains the class of which it is a method, so there is no necessity to use Delegate to correct scope issues.

Here is a simple application that draws successive random lines, using all the concepts discussed in this recipe:

package {
    import flash.display.Sprite;
    import flash.events.Event;
    
    public class ExampleApplication extends Sprite {
        
        public function ExampleApplication( ) {
            graphics.lineStyle(1, 0, 1);
            addEventListener(Event.ENTER_FRAME, onEnterFrame);
        }

        private function onEnterFrame(event:Event):void {
            graphics.lineTo(Math.random( ) * 400, Math.random( ) * 400);
        }
    }
}

Section 1.6: Responding to Mouse and Key Events

Problem

You want to do something in response to a mouse or keyboard action.

Solution

Listen for and handle mouse or key events.

Discussion

Handling mouse and key events is very similar to handling the enterFrame event, as discussed in the Recipe 1.5, but does require a little work. For mouse events, the main application class will not receive these directly, so it must listen for them on another object in the display list. (For a complete discussion of the display list, see Chapter 5.) The following example creates a sprite, adds it to the display list, and draws a rectangle in it:

package {
    import flash.display.Sprite;
    import flash.events.MouseEvent;
    
    public class ExampleApplication extends Sprite {
        private var _sprite:Sprite;
    
        public function ExampleApplication( ) {
            _sprite = new Sprite( );
            addChild(_sprite);
            _sprite.graphics.beginFill(0xffffff);
            _sprite.graphics.drawRect(0, 0, 400, 400);
            _sprite.graphics.endFill( );

Note that the mouse event names are defined in the MouseEvent class, and the handler methods get passed an instance of the MouseEvent class, so you'll need to import that class. Then you can add mouse listeners to this sprite:

            _sprite.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
            _sprite.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
        }

Next, define the two handler methods, onMouseDown and onMouseUp:

        private function onMouseDown(event:MouseEvent):void {
            _sprite.graphics.lineStyle(1, 0, 1);
            _sprite.graphics.moveTo(mouseX, mouseY);
            _sprite.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
        }
        
        private function onMouseUp(event:MouseEvent):void
        {
            _sprite.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
        }

The onMouseDown methods sets a drawing line style on the new sprite and moves the drawing cursor to the mouse position. It then adds yet a third mouse listener for the MouseMove event.

The onMouseUp methods removes that listener via the removeEventListener method. This has the same syntax as addEventListener, but tells the class to stop listening to the specified event.

Finally, define onMouseMove and close up the class and package:

        private function onMouseMove(event:MouseEvent):void {
            _sprite.graphics.lineTo(mouseX, mouseY);
        }
    }
}

This creates a simple event-driven drawing program.

Keyboard events are a little easier to handle. The only requirement for listening and responding to keyboard events is that the object that receives the events must have focus. You do this for the main application by adding the line:

stage.focus = this;

The following example shows a simple class that listens for the keyDown event and traces out the character code for that key. This also demonstrates how to use some of the data contained in the event object passed to the handler method. Note that keyboard events use the class KeyboardEvent.

package {
    import flash.display.Sprite;
    import flash.events.KeyboardEvent;
    
    public class ExampleApplication extends Sprite {
        public function ExampleApplication( ) {
            stage.focus = this;
            addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
        }
        
        private function onKeyDown(event:KeyboardEvent):void {
            trace("key down: " + event.charCode);
        }
    }
}

See Also

Recipe 1.5

Pages: 1, 2, 3, 4

Next Pagearrow