The following sections describe fundamental changes to how movie clips are perceived in ActionScript 3.0.
In prior versions of ActionScript, the MovieClip object was the center of the universe as it contained all the commands for working with timelines and containers for visual content. Though the MovieClip class worked well for controlling content, it had some disadvantages in structure, flexibility, and the granularity of its API.
The first thing I noticed in ActionScript 3.0 was the updated MovieClip API. In ActionScript 3.0, the MovieClip API no longer contains many of the commands I used routinely. One of the improvements of the ActionScript 3.0 language is the change in the granularity of the APIs. The majority of the MovieClip API has moved to the DisplayObject and DisplayObjectContainer classes, which the MovieClip class inherits from. The MovieClip API is now used primarily to traverse a timeline.
You need to know this information as you'll probably spend some time looking through the ActionScript 3.0 Help documentation to find what commands are available. Here's the list of the classes from which the MovieClip class inherits:
MovieClip › Sprite › DisplayObjectContainer › InteractiveObject › DisplayObject › EventDispatcher › Object
Notice that the MovieClip class subclasses the Sprite class. A Sprite is essentially a movie clip without a timeline. It's lighter weight and recommended for creating visual objects that don't need access to timeline control.
To find out everything a movie clip can do, review the documentation for each class in the inheritance chain.
Creating nested levels of movie clip instances has been a part of Flash since long before ActionScript was a player in the mix. When ActionScript first evolved it treated movie clips in code the same way it treated movie clips at authortime. In ActionScript 3.0, this isn't the case.
Timelines in ActionScript 3.0 are
perceived through the notion of a display list. The display list has a single stage property and a root property for
each SWF loaded into the movie. When movie clips and other visual objects are
instantiated in ActionScript they are not explicitly assigned to a timeline. It's
an odd notion if you have experience dynamically creating movie clips, but it
has the advantage of being able to instantiate a movie clip and have it remain
invisible until you decide to show it in the display list. Furthermore, you can
display the new instance in any timeline you like, not just the timeline it was
instantiated on.
Movie clip instances are display objects
when they are instantiated. When a movie clip instance is associated with the
display list, the movie clip then becomes active as a display object container
itself. That means two things. First, once the movie clip is instantiated and
added to the display list, it becomes capable of displaying and managing child
instances within itself. Second, until the movie clip instance is added to the
display list, it isn't capable of displaying children or accessing the stage or root properties of
the display list.
In ActionScript 3.0, you use the addChild method to see a display object appear on the Stage. For example, suppose that you want to create an instance of a ComboBox control from the library. To see the instance appear on the Stage, you would use the following code:
import fl.controls.ComboBox; var myCombo:ComboBox = new ComboBox(); // This produces an error trace(myCombo.stage) // This works addChild(myCombo); trace(myCombo.stage)
The addChild call above adds
the myCombo instance to the
display list. At that time the myCombo instance appears on the Stage and gains
access to the stage, root, and parent properties.
Notice that instead of using the attachMovie method, the myCombo instance is
created using the new keyword.
ActionScript 3.0 displays an error when you try to access an instance that is undefined. Often this happens when you declare a variable reference for the instance but haven't actually instantiated an object into the reference and added it to the display list. It's a timing issue in most cases.
To validate against an undefined
instance in the display list, use the getChildByName method, as
shown in the following code:
var myInstance:MovieClip = getChildByName("instanceNameInQuestion");
if( myInstance!= null )
{
// Then do something...
}
The code above uses the instance name to
test if the instance exists in the display list. If the result is null, then the
action isn't performed and an error does not occur. You can also use try..catch statements to prevent
player execution from stopping due to an unhandled error.
In ActionScript 3.0, the underscore (_) has been eliminated from the property names. In some cases, the way that values are set for common properties has also been updated.
The alpha property of a movie clip is now set on
a scale of 0 to 1 instead of 0 to 100. For example, 50% opacity would be set as
follows:
myInstance.alpha = 0.5;
The scaleX and scaleY property of a display object are now
set in a similar way. For example, 150% of normal scale would be set as
follows:
myInstance.scaleX = 1.5; myInstance.scaleY = 1.5;
The this alias can be used in ActionScript 3.0 and it behaves as it does in previous
versions of ActionScript. The _global path does not
exist in ActionScript 3.0. Try to create a class with static properties if you
need to use global references in ActionScript 3.0. The _parent property can be accessed as the parent property of any display object when
added to the display list. The _root property is now
relative to each SWF loaded in the movie and can be accessed through the root property when a
display object is added to the display list. The stage property can be used often in the same
way you used to use the _root property. The stage property is
available to any display object when added to the display list.
The swapDepths and getNextHighestDepth methods no longer exist in ActionScript
3.0. Instead you'll use the DisplayObjectContainer methods associated with a movie clip
container added to the display list. The terminology in ActionScript 3.0 is
based on the display object's "index" in the list of child objects,
instead of the concept of "depth."
For example, to send the myInstance clip to the top of the stacking order, use the following code:
setChildIndex(myInstance, numChildren - 1);
As with other changes to the MovieClip
API, the drawing API has been moved to the graphics property of a display object. Other
than its new location, the process for using it is the same—with a few
noticeable enhancements. Some of my favorite new features include the drawRect
and drawEllipse shortcut commands.
The following code shows how to dynamically draw a rectangle and then apply the rectangle as a mask to another instance. The mask object has no timeline, so it is created as a sprite instead of a movie clip:
import flash.display.Sprite; // Create mask var maskArea:Sprite = new Sprite(); maskArea.graphics.beginFill(0xFF0000); maskArea.graphics.drawRect(-29.5, -22.5, 59, 46); addChild(maskArea); // Apply mask myInstance.mask = maskArea;