ActionScript 3.0

The following are the ActionScript 3.0 versions of the two previous
scripts. Only language version-specific comments are included here so, if
you’re unclear on overall functionality, see the equivalent ActionScript
2.0 section.

The following is an explanation of ActionScript 3.0-specific
issues that appear in the main timeline frame script.

Import

Notice in Line 1 that the class path has changed from
mx to fl.

FlashVars

FlashVars are no longer
stored as global variables in the root timeline. Instead, they’re
stored in the parameters object
of the LoaderInfo instance of
the root, as seen in line 4.

TextFormat

Although you can use appropriate string values, it is a best
practice to use relevant constants for many property values in
ActionScript 3.0. In this case, the format’s align property is populated with the
RIGHT constant of the TextFormatAlign class, used in line
8.

The application of the TextFormat instance in line 14 has been
changed from setNewTextFormat()
to defaultTextFormat().

TextField

All display objects are created with a simple consistent
new<class
name>()
structure. The ActionScript 2.0 TextField creation method is
replaced with the ActionScript 3.0 instantiation (line 9) and
followed by the assignment of property values (lines 10 through
14).

Depth Management

The ActionScript 3.0 display list automatically handles
depth management so you don’t have to manually assign levels or
worry about methods like getNextHighestDepth() or the DepthManager. As such, you don’t see any
level assignments in any of the object instantiation
routines.

However, you can still control depths. For example, you
still have a swapDepths()
method for moving the background image below the text field, as
seen in line 14 of the ActionScript 2.0 main timeline frame script
code. However, you have an easier way to handle this when objects
are added to the display list. In ActionScript 2.0, existing
objects are replaced when a new object is added to the same level.
ActionScript 3.0, however, moves all objects above the target
level one level higher, and then inserts the addition where
specified.

Therefore, you can easily place the background image behind
the text field when the image is added, as seen in line 18. The
addChildAt() method is used,
specifying level 0. The background image appears in level 0, and
the text field is moved to level 1.

Variable Declaration

While you can in some cases omit typing a variable, all
variables must be declared with the var identifier.

Image Loading

Rather than creating an empty movie clip, a Loader display object is used lines (17
through 19). Instead of using the image path as a string for the
load() method, ActionScript 3.0
requires a consistent use of the URLRequest class for processing
the URL prior to use.

Sound

Although the creation of the Sound instance is the same (line 21),
sound management diverges significantly from that point on.
Loading is similar, with a change of method name to the more
consistent load() and the
ever-needed URLRequest instance
instead of a string. The event handling is significantly different
in ActionScript 3.0 (and is explained in a moment), but the idea
behind it, as it pertains to sound, is the same: wait until the
sound is loaded, and then proceed.

However, three new classes play a big part of sound
management. First, each sound is typically played into its own
discrete sound channel, an instance of the SoundChannel class (lines 25 and 26).
This step is a requirement if you wish to perform sound
transformations. Where the volume and pan properties existed in the Sound class in ActionScript 2.0, they’re
now accessible through the soundTransform property of the SoundChannel class.

To effect such a change, an instance of the second new
class, SoundTransform is
derived from the SoundChannel
soundTransform property (line 27), the desired property
is changed (volume, line 28)
and the new instance is reapplied to the SoundChannel soundTransform property
once again (line 29).

The third new class, not used in this example, is the
SoundMixer class. This class
lets you manipulate all the sounds at once. The isolation of
sounds into their own discrete channels lets you control each
sound separately and with greater precision.

Handling Events

Event handling is very different in ActionScript 3.0. For
detailed information, see Chapter 14, How Do I Work with Events?. From a migration
standpoint, event handlers are no longer attached to the target of
the event. Instead, event listeners are created, specifying an
event to listen for, and a function to trigger upon an occurrence
of that event (lines 23 through 31).

A mandatory parameter is used to receive information from
the event that can be used inside the function. For example, the
target of the event in the mentioned listener is the snd object. That is referenced by
evt.target in lines 26 and
30.

The events are specified as constants, as discussed
previously with the TextFormat
align property, and optional parameters allow more granular
control over when the event is processed (capture or
target/bubbling phases and priority) as well as whether weak
references are used for a little backup help in the memory
management department.

Finally, you should remove the listener when you no longer
need it, for optimal memory management (line 30). You also find
event listeners in lines 45 through 48, and 55 through 65.

Void

Void is now lower case (lines 24, 46, 56).

Percent Values Scale

Percent value scales are now from 0 to 1 (instead of 0 to
100).

Dynamic Creation of Movie Clip and Instantiation of Custom
Class

ActionScript 3.0 lets you much more easily use custom
classes as display objects. You don’t need to rely on a
Library-based symbol, or more convoluted methods, to instantiate
the class. Instead, provided the class extends MovieClip, Sprite, Shape, or another applicable
display object, you just need to instantiate it the way you would
any other display object: new
<classname>(); (line 33). You must then add the
instance to the display list for the user to see it.

Another movie clip is dynamically generated in line 36. Note
the simplicity of creating an empty movie clip container (to hold
buttons). Rather than using one of many methods, such as createEmptyMovieClip(), the consistent
new MovieClip() approach is all
you need, coupled with the addChild() method on line 38.

Property Underscores

Line 37 is one example of the fact that ActionScript 3.0
properties are not preceded by an underscore.

Custom Button Instantiation

The same custom button used in the ActionScript 2.0 version
can be instantiated here as a proper button (SimpleButton, line 41) rather than using
a MovieClip method and typing
the instance as a MovieClip or
Object. It’s then positioned,
and added to the display list (lines 42 and 43, respectively).

Dynamic versus Sealed Classes

In this case, however, the SimpleButton class is a sealed class, so
you can’t add the site URL used by the button as a property. In
this case, it’s stored in a standard variable.

You could have brought these two examples into a more
parallel structure by using movie clips for buttons in both cases,
because MovieClip is a dynamic
class and would allow the addition of a property. However, the
purpose of this chapter is not to change the way you want to work,
but to understand how best to migrate a legacy project to the new
syntax of ActionScript 3.0.
Taking advantage of the new SimpleButton class is desirable, and
even lets you create a button entirely from code (no Library
assets) if preferred.

To see an exact parallel, you can add an example property to
the text field instance in both versions of the project. In the
ActionScript 2.0 version, adding

txtFld.inUse =
true;

after line 10 works. However, adding the same line in the
ActionScript 3.0 version after line 15 generates an error because
the TextField class is sealed
in ActionScript 3.0.

Opening a URL

Line 47 shows the new syntax for accessing a URL, using the
navigateToURL() method and
URLRequest instance.

Dynamically Instantiating a Component

Adding a component to your project on the fly is really no
different from adding a movie clip or other display object. Just
use the Button class as you
would another display object class, as seen in line 50. (As with a
custom asset, a Button component must be in your
Library.)

Accessing Objects by Instance Name

You can’t access a dynamically created object directly by
instance name. That is, setting the name property in ActionScript
3.0 doesn’t make it possible to reference the object using the dot
syntax object model. Instead, you must use the getChildByName() method, as seen in line
57.

Using the Graphics Class (formerly the Drawing API)

Although the clear(),
beginFill(), and endFill() methods are the same in
ActionScript 3.0, they’re methods of the Graphics class, accessed through the graphics property instance of each
relevant display object. Further, you don’t need a custom function
to draw a rectangle, as the new drawRect() method does that for
you.

Particles Class

The Particles class
functionality is the same in ActionScript 3.0. It creates each particle,
establishes its behavior, and ultimately removes it from the
project.

As with the ActionScript 2.0 section, basic syntax issues
discussed in the main timeline won’t be mentioned again.

Class Structure

Line 1 shows that all ActionScript 3.0 classes must be
enclosed in a package statement. This line
would also be where you would include a path to the class, if
desired. Lines 8 and 14 remain consistent with ActionScript
2.0.

Import

Lines 3 through 6 import all the classes to make them
accessible to the compiler. Unlike ActionScript 2.0, even classes
in Flash Player must be imported.

Class Properties

Lines 10 through 12 are consistent with ActionScript
2.0.

Number Data Types

Lines 10 and 11 use the int data type because you don’t need
float values. You can also see this characteristic in lines 40 and
65. 40 is a good example, as the uint data type is used, because a color
value can’t be negative.

Much has been made of the performance of the uint data type and, to a lesser degree,
the int data type, so you can
decide whether or not to use them. This is just an example.

Access to Stage

Unlike ActionScript 2.0, the stage isn’t a global object.
Instead, you must access the stage through a display object. The
Particles class both extends
MovieClip, and is added to the
display list in the main timeline frame script, so you can access
the stage without passing a reference to it through the
constructor.

However, you can access the stage only after the display
object has been added to the display list. Therefore, this class
can’t access the stage within its constructor, as the class hasn’t
yet been fully initialized. Instead, a new event listener is added
to listen for the Event.ADDED_TO_STAGE event (line 15). Once this
event fires, the display object is part of the display list, and
the stage reference doesn’t return null.

Lines 21 through 25 contain the function used for this
purpose and, because the listener is no longer necessary, it’s
removed upon execution of this function. (The this keyword is not strictly needed
because the relevant scope is the class itself, but it’s been
added to emphasize that you’re accessing the stage through a
display object.)

Class Enter Frame Event

The use of the enter frame event for the class is the same;
however, note that, because event handlers no longer exist, you
can’t just name a function onEnterFrame() and expect it to work.
You must convert that structure to an event listener design, seen
in lines 16 and 36 through 38.

Method Closures

You no longer need the Delegate class, as ActionScript 3.0
supports method closures.

Preloading Sounds

The sound preloading routine hasn’t changed, and doesn’t
include any ActionScript 3.0 syntax issues that haven’t already
been discussed, with one small exception. If you pass a valid
URLRequest instance to the Sound class constructor, as in line 31,
the load() method is
automatically called.

It’s also a good idea to look this method over with regard
to removing listeners. It’s important to remove the load complete
listener from _tempSound after
each sound has been loaded (or, if you prefer, after the last
sound has loaded) to prevent the listener from remaining on the
last sound.

Particle Creation

ActionScript 3.0 has nothing unique in the makeParticle() method that hasn’t been,
or won’t be, discussed elsewhere. However, be sure to read about
changes to default values, accessing objects in the parent, and
using the Drawing API (now commonly referred to as the Graphics class).

Default Values

ActionScript 3.0 allows the assignment of default values to
method arguments, as seen in line 40. This action makes the
associated arguments optional, but all optional arguments must
appear at the end of the method signature.

Further, default values for data types have changed in
ActionScript 3.0. For example, line 44 can no longer test for
undefined, as the default value
for number data types is NaN
(not a number). As such, you must use the isNan() method to validate its
value.

As is true with many intentionally injected migration issues
in this exercise, this could
have been handled a different way. This property could have been
initialized in line 10, for example, but was not so this issue
could be discussed.

Accessing Objects in the Parent

In Lines 58 and 59, the particle must cast the type of its
parent before it can access the parent’s methods or properties.
Without this step, the compiler knows only that the parent’s a
display object container, but not what kind. The compiler,
therefore, doesn’t recognize the txtFld property of the parent.

When cast to a MovieClip,
however, the compiler knows that MovieClip is a dynamic class and can,
therefore, have custom properties. It then looks for txtFld in the parent. and finds the text
field you created.

Manipulating Text Fields

When adding text to the text field (line 58), the appendText() method was used, as it’s
much faster than the compound operator +=. Furthermore, the property scrollV must be updated to the value of
maxScrollV (line 59).

Particle Sound

Nothing about the particleSound() method that is unique to
ActionScript 3.0 hasn’t already been discussed. Line 64 checks to
make sure the particle’s Sound
instance hasn’t already been created, and that _soundNum has been incremented to be
sure the sounds have preloaded. Line 65 creates a random number
within the count of available sounds, line 66 creates an instance
of the Sound class and loads
the sound, and lines 67 and 68 create a SoundChannel instance and play the
sound.

Particle Behavior

The behavior of the ActionScript 3.0 particles isn’t unique,
but a few very important concepts should be discussed. To begin,
the first number of the product used for the sound transformation
pan value is calculated using
the particle’s x divided by the
Particles class’ x (line 81). This step’s in contrast to
the ActionScript 2.0 calculation, which divides the first number
by the class’s parent’sx value (line 73 of the ActionScript 2.0
class code). ActionScript 2.0 requires the Library movie clip to
instantiate the class this way, so the movie clip must be
referenced in the calculation. ActionScript 3.0 lets you add this
class to the display list directly, so only the class needs to be
referenced.

Next, you must stop the sound, and remove the event
listener, before removing the particle. Otherwise, the particle
and its attendant objects, (such as listeners) won’t be collected
by the garbage collector and purged from memory.

The compiler must be told that the object is a MovieClip to prevent an error from
occurring, because the compiler sees only the target of the method
as an Object that may or may
not be removable. However, this issue has already been addressed
in the “Accessing Objects in the Parent (Type Casting)” section of
this discussion.

Getter

Nothing unique about the count() getter method is unique to
ActionScript 3.0 hasn’t already been discussed

Migration Sample Summary

This is a small example of one possible migration path used to
update a legacy project to ActionScript 3.0. Although awkward coding
choices were made to show the largest number of migration issues practical
in this size example, the exercise is still relatively close to a
real-world scenario.

Having read this chapter, you may want to see if you can migrate
this example on your own. Once you try the process a few times, you’ll
have a pretty good idea of what you need, and you can evaluate the
effectiveness of migration on a case-by-case basis. Depending on the
extent of the changes, you may wish to use the old project as a kind of
template, and then code the new version from scratch.

This excerpt is from The ActionScript 3.0 Quick Reference Guide. If you're ready to give your Flash projects a considerable performance boost, learning ActionScript 3.0 is a must. This Quick Answer Guide is designed specifically to help Flash designers and developers make the leap from ActionScript 2.0 to the new object-oriented ActionScript 3.0 quickly and painlessly. You'll learn key differences between the two language versions, allowing you to more easily leverage ActionScript 3.0 using Flash CS4 and other Adobe technologies like Flex and AIR.

Recommended for You

Sign up today to receive special discounts, product alerts, and news from O'Reilly.