Learning ActionScript 3.0: Chapter 4, The Display List
Pages: 1, 2, 3, 4, 5, 6
Take a look at the function in action. Figure 4-4 shows a sample file that will be analyzed. The rectangle and circle movie clips, with their instance names, are indicated in the figure. Within the rectangles, a shape gives the fill and stroke appearance. Inside the circles, a shape provides the fill and stroke as well as a static text element.
When the function runs, the following is traced to the output window, showing all children of the stage. It lists display containers by name and object reference, and display objects by object reference alone.
root1 [object MainTimeline] largeContainer [object largeContainer_1] [object Shape] smallContainer [object smallContainer_2] [object Shape] child2 [object MovieClip] [object Shape] [object StaticText] child0 [object MovieClip] [object Shape] [object StaticText] child1 [object MovieClip] [object Shape] [object StaticText]
You can improve the readability of the trace by adding indents to show the parent-child relationship of the traced objects. The following is seen in trace_display_list2.fla (bold lines are new or changed).
1 function showChildren(dispObj:*, indentLevel:Number):
void {
2 for (var i:int = 0; i < dispObj.numChildren; i++) {
3 var obj:DisplayObject = dispObj.getChildAt(i);
4 if (obj is DisplayObjectContainer) {
5 trace(padIndent(indentLevel), obj.name, obj);
6 showChildren(obj, indentLevel + 1);
7 } else {
8 trace(padIndent(indentLevel) + obj);
9 }
10 }
11 }
12
13 showChildren(stage, 0);
14
15 function padIndent(indents:int):String {
16 var indent:String = "";
17 for (var i:Number = 0; i < indents; i++) {
18 indent += " ";
19 }
20 return indent;
21 }
The function in lines 15 through 21 takes a desired indent level and returns four spaces for each indent specified. For example, the first child will have no indent, or an indent level of 0. Therefore, it will return four spaces zero times, for no indent effect. The first nested child will have an indent level of 1, so the function will return four spaces of indent. A child at a second tier of nesting will have an indent level of 2, so the function will return eight spaces of indent, and so on.
We can indicate the number of indents by passing a value into a second parameter in the main function, in the form of indentLevel, as seen in line 1. Now that this second parameter exists, we've changed the calls to the function, at lines 6 and 13, to add the indent value. The process begins at line 13 with an indent level of zero. Each recursive call, however, must be indented one more level, so line 6 adds 1 to the indentLevel argument each time the function is called.
Finally, lines 5 and 8 add the new spaces, for each level of indent, that are returned by the padIndent() function. The result, shown here, is a more human-readable output with the indents representing nested children.
root1 [object MainTimeline]
largeContainer [object largeContainer_1]
[object Shape]
smallContainer [object smallContainer_2]
[object Shape]
child2 [object MovieClip]
[object Shape]
[object StaticText]
child0 [object MovieClip]
[object Shape]
[object StaticText]
child1 [object MovieClip]
[object Shape]
[object StaticText]
If you wish, you may also change the string returned from the padIndent() function to another number of spaces, or even another character such as a period.
This excerpt is from Learning ActionScript 3.0. Learning ActionScript 3.0 gives you a solid foundation in the Flash language and demonstrates how you can use it for practical, everyday projects. The book does more than give you a handful of sample scripts, defining how ActionScript and Flash work. It gives you a clear look into essential topics such as logic, event handling, displaying content, migrating legacy projects to ActionScript 3.0, classes, and much more. Written for those new to the language, this book doesn't rely exclusively on prior knowledge of object-oriented programming (OOP). Instead, it helps you expand your skillset by first focusing on clear, concise examples in the timeline, evolving into OOP examples over time-allowing you to choose the programming approach with which you are most comfortable.
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.
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.
In the previous, simple examples, we've created display objects without content. In , 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.