The Display List: Chapter 4 - Learning ActionScript 3.0
Pages: 1, 2, 3, 4

13 swapChildrenAt(0,1);

Finally, you can specify a new index for any existing display object. The following new example, seen in the setChildIndex.fla source file, takes advantage of the event propagation discussed in to automatically bring any display object that is rolled over with the mouse to the top of the visual stacking order.

1 addEventListener(MouseEvent.MOUSE_OVER, onBringToTop, false, 0,
  true);
2
3 function onBringToTop(evt:MouseEvent):void {
4     setChildIndex(MovieClip(evt.target), numChildren-1);
5 }

This script accomplishes its task by setting the child's display list index to the highest level possible. The script first determines the number of children in the display object container (in this case, the main timeline) and then, because ActionScript arrays are zero-based (meaning the first item is item 0), it subtracts 1 to get the highest existing index in the display list. For example, if there are three items in the display list, their indices would be 0, 1, and 2. The number of children would be 3, and 3 minus 1 equals 2—the highest index in the list. Figure 4-7 illustrates.

Warning: Using prior versions of ActionScript, some developers specified depths known to be higher than any existing depth as a means of ensuring that an object would always be on top of all other objects. This is not possible in ActionScript 3.0. Specifying a level that is higher than the number of children in the display list will result in the "supplied index is out of bounds" error discussed in the prior section, "Preventing out of bounds errors."

By setting every item rolled over to the highest possible index, all other items are pushed back, popping the rolled-over item to the highest z index.

Example
Figure 4-7: In setChildIndex.fla, rolled-over items pop to the top

Reparenting Children

Another task that is vastly simplified by the display list is moving a child from one parent to another. In the reparenting.fla source file, a moon can be moved to either of two night skies, just by clicking that sky (). Both skies are also draggable, demonstrating that the moon will move with the night sky.

Example
Figure 4-8: In reparenting.fla, the moon and stars become a child of the clicked sky

The script begins by adding the moon to the first sky (on the left) as its starting position. It then adds an event listener to the main timeline to allow any child that receives a mouse down event to call onDrag() and then, on mouse up, call onDrop().

1     sky1.addChild (moon);
2
3     this.addEventListener (MouseEvent.MOUSE_DOWN, onDrag, false, 0,
      true);
4     this.addEventListener (MouseEvent.MOUSE_UP, onDrop, false, 0, true);

The onDrag() function starts by stopping its progress (by using the return keyword to leave the function) if the clicked item (the target of the mouse down event) is the moon itself. This prevents the circular error of trying to add a display object to itself.

This function then adds the moon to the sky that was clicked. This action removes the moon from its previous parent and adds it to the clicked item, therefore reparenting the moon. The function then enables dragging of the clicked item.

5 function onDrag(evt:MouseEvent):void
6     if (evt.target == moon) return;
7     evt.target.addChild(moon);
8     evt.target.startDrag();
9 }
10

Finally, when the mouse up event is received, the onDrop() function disables dragging on the clicked item.

11 function onDrop(evt:MouseEvent):void {
12     evt.target.stopDrag();
13 }

As you can see, by using the addChild() method, you can move a display object from one parent container to another, resulting in the child inheriting all the relevant attributes of its new parent.

Section 4.5: A Dynamic Navigation Bar

Now it's time to tie much of this together and create a dynamic navigation bar. This project will create a five-button navigation bar that will be centered on stage as shown in Figure 4-9. To simulate functionality, each button will trace its name to the Output panel when clicked.

Example
Figure 4-9: A dynamically generated navigation bar

Here is the start of the script for the navigation bar:

1 var btnNum:int = 5;
2 var spacing:Number = 10;
3
4 var navBar:Sprite = new Sprite();
5 addChild(navBar);

The script begins at lines 1 and 2 by initializing the number of buttons used and the space in pixels between each button. It then creates a container for the buttons in line 4. This navigation bar doesn't need a timeline so, for added efficiency, a sprite will be used as the container rather than a movie clip. Next, line 5 adds the sprite to the display list.

6 var btn:SimpleButton;
7 for (var i:uint = 0; i <btnNum; i++) {
8     btn = new Btn();
9     btn.name = "button" + i;
10    btn.x = spacing + i * (btn.width + spacing);
11    btn.y += 5;
12    btn.addEventListener(MouseEvent.CLICK, onTraceName, false, 0,
      true);
13    navBar.addChild(btn);
14 }

A for loop then creates the total number of buttons. Each time through the loop, a new button is created from a button symbol in the library with the linkage class of Btn (line 8). An instance name is assigned to the button, combining the string "button" and the loop counter value (line 9). Thus, the first button is called button0, the second is called button1, and so on.

The current button is positioned horizontally (line 10), offset by the spacing set in line 2, plus the width of the button and another spacing gap for each button in the loop. Therefore, the first button is positioned only 10 pixels to the right of the container's registration point (spacing, plus zero times the sum of the width of the button and spacing). The last button is positioned 10 pixels to the right of the container's registration point plus 4 times the width of the button and spacing. The vertical position is also set, moving the button down 5 pixels.

As the last instructions in the loop, a mouse click listener is added to the button, specifying the onTraceName() function to be called when the event is received (line 12), and the button is added to the navBar parent (line 13).

15 var bg:MovieClip = new NavBarBack();
16 bg.width = btnNum * (btn.width + spacing);
17 bg.width += spacing;
18 navBar.addChildAt(bg, 0);

Starting with line 15, a background is added to the navBar. Its width is set to the total number of buttons times the sum of the button width and spacing, plus a spacing gap to the right of the button. The background is then added to the navBar at position 0, ensuring that it's placed behind all the buttons.

19 navBar.x = (navBar.stage.stageWidth - navBar.width)/2;
20 navBar.y = 20;

The finished navBar is then centered horizontally at an x coordinate determined by the width of the stage minus the width of the navBar, divided by 2 for a left and right margin. It is also positioned vertically at a y coordinate of 20 pixels.

21 function onTraceName(evt:MouseEvent):void {
22    trace(evt.target.name);
23 }

Finally, the onTraceName() function, identified in the event listener as the function to execute when the mouse click was received, traces the name of the clicked button.

This exercise demonstrates how to create a simulated navigation bar using the display list, when no assets previously existed on the stage. Later in the book, you will learn how to create the buttons and draw the background shape entirely with ActionScript, removing the need to precreate these assets as library symbols.

Section 4.6: What's Next?

The display list is among the most important new introductions to ActionScript 3.0. It is worth the effort to explore the properties, methods, and events of the various display list classes—starting with the contents of this chapter, and then delving into the Flash Player help system, and additional resources, as you gain experience. Experimenting with the display list will show you that it is easy to use and, if you have experience with prior versions of ActionScript, you will soon find that it is much simpler and more consistent than equivalent methods in ActionScript 1.0 or ActionScript 2.0.

Next, we'll discuss timeline control. Regardless of whether you are creating lengthy linear animations or single-frame applications, you are likely to require some level of control over the main timeline or movie clips. ActionScript 3.0 offers a few new features for you to try out.

In the next chapter, we'll discuss:

  • Controlling playback of your animations and applications by moving the playhead with ActionScript
  • Using new ActionScript to parse frame label names from timelines and scenes
  • Changing the frame rate of movie playback for the first time

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.

buy button