O'Reilly logo

Learning ActionScript 3.0 by Zevan Rosser, Rich Shupe

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Adding and Removing Children

The previous section described the parts of the display list, and how to analyze an existing list. But you'll also need to know how to add to, and remove from, the display list at runtime. In previous versions of ActionScript, you needed to rely on varying methods to add items to the stage. For example, you needed to use separate methods for creating a movie clip, placing a library movie clip on stage, or duplicating a movie clip. Using the ActionScript 3.0 display list, you only need one approach to create a movie clip. You will use new MovieClip(). Even adding a precreated movie clip from the library is consistent with this syntax, as you'll soon see.

Using addChild()

Adding a display object to the display list requires just two simple steps. The first is to create the object—in this case, an empty movie clip (that is, a movie clip created dynamically, but that currently has no content):

var mc:MovieClip = new MovieClip();

This literally creates the movie clip but does not display it. In order for the movie clip to display, you must add it to the display list using the addChild() method:

addChild(mc);

You can also specify a particular target for the movie clip, as long as that target is a display object container. (Remember, you can't add children to display objects like shapes, videos, text elements, and so on, because they are not display object containers.) So, if you instead wanted to add the mc movie clip nested inside another movie clip called navBar, you would change the second step to:

navBar.addChild(mc);

We've been using movie clips in our examples, but it's also as straightforward to add other display objects. Two simple examples include creating a sprite and a shape:

var sp:Sprite = new Sprite();
addChild(sp);

var sh:Shape = new Shape();
addChild(sh);

You don't even have to specify a depth (visible stacking order), because the display list automatically handles that for you. In fact, you can even use the same addChild() method for changing the depths of existing display objects, but we'll discuss depths in greater detail later in this chapter.

Adding Symbol Instances to the Display List

In the previous, simple examples, we've created display objects without content. In Chapter 8, we'll show you how to draw with code, so you can create content for these movie clips, relying solely on code for small file size and more dynamic control.

However, you will frequently find the need to use custom art in your files, and in those situations code-only solutions will not do. So, in this chapter, we're going to focus on dynamically adding movie clips that already exist in your library. In the accompanying source file, addChild.fla, you will find a unicycle in the library. To add this movie clip to the display list using ActionScript, you must set up the library symbol first.

In prior versions of ActionScript, there were two ways of doing this. The first approach was to assign the symbol a linkage identifier name. This was similar to an instance name for library symbols, in that you could reference the symbol by name using ActionScript. The second way was to assign a class to the movie clip so that it could be created when you created an instance of the class, and also have its own code to execute.

In ActionScript 3.0, these two approaches are unified. Rather than using the linkage identifier, you simply use a class name to reference a symbol in all cases. When you've written a class for the symbol, which we'll do in later chapters, the symbol will behave accordingly. However, when you just want to reference the symbol, Flash will automatically create an internal placeholder class for you, and use the class name to dynamically create the symbol when requested. This approach also allows you to easily add classes later while changing little or nothing in your file.

Continuing our movie clip example, to add a class name to a symbol, select the movie clip in your library, and then click the Symbol Properties button (it looks like an "i" at the bottom of the library) for access to all the symbol properties. Alternatively, you can focus only on the linkage information by choosing Linkage from the library menu, as seen in Figure 4-5.

Accessing a symbol's linkage information

Figure 4-5. Accessing a symbol's linkage information

In the resulting dialog, seen in Figure 4-6, click to enable the Export for ActionScript option, and add a name to the Class field. When you start working with classes, you will follow a few simple rules and conventions, one of which is to capitalize the first letter of your class name. This is a bit different from naming a variable, where you might choose to use a lowercase first letter, so it's a good idea to get into this practice now. In the addChild.fla source file, we've used the class name Unicycle.

Entering a class name for a movie clip in the library Linkage Properties

Figure 4-6. Entering a class name for a movie clip in the library Linkage Properties

You will also likely notice that Flash adds the MovieClip class (in this case) to the Base class field for you. This makes it possible to automatically access the properties, methods, and events available to the MovieClip class. For example, you can automatically manipulate the x and y coordinates of your new custom movie clip.

Now that you've given your movie clip a class name, you can create an instance of that custom movie clip class the same way you created an instance of the generic movie clip class. Instead of using MovieClip(), however, you will use Unicycle() to create the movie clip. The same call of the addChild() method is used to add the newly created movie clip to the display list, as seen in the following code. The code and required movie clip exist in the accompanying source file addChild.fla.

var cycle:MovieClip = new Unicycle();
addChild(cycle);

Using addChildAt()

The addChild() method adds the display object to the end of the display list, which places the object at the top-most z index. This makes it very easy to place items on top of all other items. However, it's also useful to be able to add a child at a specific position in the display list. For example, you may wish to insert an item into the middle of a vertical stack of display objects.

This example, found in the addChildAt.fla source file, adds a movie clip with the class name Ball to the start of the display list with every mouse click. The ultimate effect is that a new ball is added below the previous balls, and positioned up and to the right 10 pixels, every time the mouse is clicked.

1 var inc:int = 0;
2
3 stage.addEventListener(MouseEvent.CLICK, onClick, false, 0, true);
4
5 function onClick(evt:MouseEvent):void {
6            var ball:MovieClip = new Ball();
7     ball.x = ball.y = 100 + inc * 10;
8           addChildAt(ball, 0);
9           inc++;
10}

Line 1 initializes a variable that will be incremented with each ball added. Line 3 adds an event listener to the stage, listening for a mouse click, so that any mouse click will trigger the listener's function. The function in lines 5 through 10 performs four basic tasks. In line 6, a new Ball movie clip is created.

Line 7 manipulates the x and y coordinates in a single instruction, setting x equal to y, which is equal to the value of an expression. This is handy when both x and y values are the same. In this case, the expression sets the new ball to x and y of 100 and adds a 10-pixel offset for each ball added. For example, when the first ball is added, inc is 0 so the additional pixel offset is 0*10 or 0. Then inc is incremented at the end of the function, in line 9. The next mouse click that calls the function will update the offset to 1*10 or 10 pixels for the second ball, 2*10 or 20 pixels offset for the third ball, and so on. Most importantly, line 8 adds the ball to the display list, but always at position 0, making sure the newest ball is always on the bottom.

Note

It is possible to manipulate display objects—such as setting properties or invoking methods—both before and after the object has been added to the display list. By doing this, you can create a display object, initialize its properties to your liking, but reserve adding it to the display list until it is needed. See the sidebar "Display Objects and References to Stage and Root" for a notable exception to this rule.

Removing Objects from the Display List and from Memory

It's equally important to know how to remove objects from the display list. The process for removing objects is nearly identical to the process for adding objects to the display list. To remove a specific display object from the display list, you can use the removeChild() method:

removeChild(ball);

Remove a display object at a specific level using removeChildAt():

removeChildAt(0);

The following example is the reverse of the addChildAt() script discussed in the prior section. It starts by using a for loop to add 20 balls to the stage, positioning them with the same technique used in the prior script. (For more information on for loops, please review Chapter 2.) It then uses the event listener to remove the children with each click.

1 for (var inc:int = 0; inc < 20; inc++) {
2     var ball:MovieClip = new Ball();
3     ball.x = ball.y = 100 + inc * 10;
4     addChild(ball);
5 }
6
7 stage.addEventListener(MouseEvent.CLICK, onClick, false, 0, true);
8
9 function onClick(evt:MouseEvent):void {
10     removeChildAt(0);
11 }

Preventing out of bounds errors

The previous script works if something's in the display list. If after removing the last ball, you click the stage again, you're warned "the supplied index is out of bounds." That's because you're trying to remove a child from position 0 of the display list, when there's nothing in the display list at all.

To avoid this problem, you can first check to see whether there are any children in the display object container that you are trying to empty. Making sure that the number of children exceeds zero will prevent the aforementioned error from occurring. The following is an updated onClick() function, replacing lines 9–11 in the previous code, with the new conditional in bold. (For more information on conditionals, please review Chapter 2.)

9   function onClick(evt:MouseEvent):void {
10    if (numChildren > 0) {
11       removeChildAt(0);
12    }
13 }

Note

If you ever want to use a for loop to remove many objects at once (everything in the display list, for example), it is easier to remove the objects from the bottom, as discussed here. This is because, as long as there is something in the display list, there will always be something in position 0, and you will avoid the index out of bounds error. For more information, consult Chapter 20 of Colin Moock's Essential ActionScript 3.0.

Removing objects from memory

As we discussed when introducing event listeners in Chapter 3, it is important to remember that inadequate asset management can result in memory leaks. It is always a good idea to try to keep track of your objects and, when you are sure you will no longer need them, remove them from memory.

Keeping track of objects is particularly relevant when discussing the display list because it is easy to remove an object from the display list but forget to remove it from RAM. Doing so will cease displaying the object, but the object will still linger in memory. The following script, a simplification of the previous example, will both remove a movie clip from the display list and from RAM.

1 var ball:MovieClip = new Ball();
2 ball.x = ball.y = 100;
3 addChild(ball);
4
5 stage.addEventListener(MouseEvent.CLICK, onClick, false, 0, true);
6
7 function onClick(evt:MouseEvent):void {
8     this.removeChild(ball);
9     //ball removed from display list but still exists
10             trace(ball);
11             ball = null;
12             //ball now entirely removed
13     trace(ball);
14
15     stage.removeEventListener(MouseEvent.CLICK, onClick);
16 }

Lines 1 through 5 are derived from the previous example, creating and positioning the ball, adding it to the display list, and adding a mouse click listener to the stage. The first line of function content, line 8, removes the ball from the display list using the removeChild() method. Although it is no longer displayed, it is still around, as shown by line 10, which traces the object to the output panel. Line 11, however, sets the object to null, marking it for removal from memory—again, shown by tracing the object to the output panel in Line 13.

Note

As an added review of best practices, line 15 emphasizes the concept of removing event listeners covered in Chapter 3. This is a good example of this practice, since using a weak reference in the last parameter of the addEventListener() method in line 5 is not reliable. Remember, weak references are a best practice backup plan, not a substitute for explicitly removing your unwanted listeners. For additional information, please review Chapter 3.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required