Book HomeActionScript: The Definitive GuideSearch this book

13.4. Movie and Instance Stacking Order

All movie clip instances and externally loaded movies displayed in the Player reside in a visual stacking order akin to a deck of cards. When instances or externally loaded .swf files overlap in the Player, one clip (the "higher" of the two) always covers up the other clip (the "lower" of the two). Simple enough in principle, but the main stack, which contains all the instances and .swf files, is actually divided into many smaller substacks. We'll look at these substacks individually first, then see how they combine to form the main stack. (The stack in this discussion has no direct relation to the LIFO and FIFO stacks discussed in Chapter 11, "Arrays".)

13.4.1. The Internal Layer Stack

Instances created manually in the Flash authoring tool reside in a stack called the internal layer stack. This stack's order is governed by the actual layers in a movie's timeline; when two manually created instances on separate timeline layers overlap, the instance on the uppermost layer obscures the instance on the lowermost layer.

Furthermore, because multiple clips may reside on a single timeline layer, each layer in the internal layer stack actually maintains its own ministack. Overlapping clips that reside on the same layer of a timeline are stacked in the authoring tool via the Modify Arrange commands.

As of Flash 5, we can swap the position of two instances in the internal layer stack using the swapDepths( ) method, provided they reside on the same timeline (that is, the value of the two clips' _ parent property must be the same). Prior to Flash 5, there was no way to alter the internal layer stack via ActionScript.

13.4.2. The Programmatically Generated Clip Stack

Programmatically generated instances are stacked separately from the manually created instances held in the internal layer stack. Each instance has its own programmatically generated clip stack that hold clips created via duplicateMovieClip( ) and attachMovie( ). The stacking order for these clips varies depending on how they were created.

13.4.2.1. How clips generated via attachMovie( ) are added to the stack

A new instance generated via attachMovie( ) is always stacked above (i.e., in the foreground relative to) the clip to which it was attached. For example, suppose we have two clips -- X and Y -- in the internal layer structure of a movie and that X resides on a layer above Y. Now further suppose we attach a new clip, A, to X and a new clip, B, to Y:

x.attachMovie("A", "A", 0);
y.attachMovie("B", "B", 0);

In our scenario, the clips would appear from top to bottom in this order: A, X, B, Y, as shown in Figure 13-1.

Figure 13-1

Figure 13-1. A sample instance stack

Once a clip is generated, it too provides a separate space above its content for more programmatically generated clips. That is, we may attach clips to attached clips.

Clips attached to the _root movie of a Flash document are placed in the _root movie's programmatically generated clip stack, which appears in front of all clips in the _root movie, even those that contain programmatically generated content.

Let's extend our earlier example. If we were to attach clip C to the _root of the movie that contained clips X, Y, A, and B, then clip C would appear in front of all the other clips. Figure 13-2 shows the extended structure.

Figure 13-2

Figure 13-2. An instance stack showing a clip attached to _root

13.4.2.2. How clips generated via duplicateMovieClip( ) are added to the stack

Each instance duplicated via duplicateMovieClip( ) is assigned to a programmatic stack in accordance with how that instance's seed clip was created:

  • If the instance's seed clip was created manually (or was duplicated using duplicateMovieClip( ) from a clip that was created manually), then the new instance is placed in the stack above _root.

  • If, on the other hand, the instance's seed clip was created with attachMovie( ), then the new instance is placed in its seed clip's stack.

Let's return to our example to see how this works. If we create clip D by duplicating clip X (which was created manually), then clip D is placed in the stack above _root, with clip C. Similarly, if we create clip E by duplicating clip D (which is derived from clip X, which was created manually), then E is also placed in the stack above _root, with C and D. But if we create clip F by duplicating clip A (which was created with attachMovie( ) ), then F is placed in the stack above X, with clip A. Figure 13-3 is worth a thousand words.

Figure 13-3

Figure 13-3. An instance stack showing various duplicated clips

13.4.2.3. Assigning depths to instances in the programmatically generated clip stack

You may be wondering what determines the stacking order of clips C, D, and E, or of clips A and F in Figure 13-3. The stacking order of a programmatically generated clip is determined by the depth argument passed to the attachMovie( ) or duplicateMovieClip( ) function, and can be changed at any time using the swapDepths( ) function. Each programmatically generated clip's depth (sometimes called its z-index) determines its position within a particular stack of programmatically generated clips.

The depth of a clip may be any integer and is measured from the bottom up, so -1 is lower than 0; 1 is higher than (i.e., in front of) depth 0; depth 2 is higher still, and so on. When two programmatically generated clips occupy the same position on screen, the one with the greater depth value is rendered in front of the other.

Layers are single-occupant dwellings. Only one clip may occupy a layer in the stack at a time -- placing a clip into an occupied layer displaces (and deletes) the layer's previous occupant.

It's okay for there to be gaps in the depths of clips; you can have a clip at depth 0, another at depth 500, and a third one at depth 1000. There's no performance hit or increase in memory consumption that results from having gaps in your depth assignments.

13.4.3. The .swf Document "_level" Stack

In addition to the internal layer stack and the programmatically generated clip stack, there's a third (and final) kind of stack, the document stack (or level stack), which governs the overlapping not of instances, but of entire .swf files loaded into the Player via loadMovie( ).

The first .swf file loaded into the Flash Player is placed in the lowest level of the document stack (represented by the global property _level0). If we load any additional .swf files into the Player after that first document, we may optionally place them in front of the original document by assigning them to a level above _level0 in the document stack. All of the content in the higher-level documents in the level stack appears in front of lower-level documents, regardless of the movie clip stacking order within each document.

Just as the programmatically generated clip stack allows only one clip per layer, the document stack allows only one document per level. If we load a .swf file into an occupied level, the level's previous occupant is replaced by the newly loaded document. For example, you can supplant the original document by loading a new .swf file into _level0. Loading a new .swf file into _level1 would visually obscure the movie in _level0, but not remove it from the Player.

Figure 13-4 summarizes the relationships of the various stacks maintained by the Flash Player.

Figure 13-4

Figure 13-4. The complete Flash Player movie clip stack

13.4.4. Stacks and Order of Execution

The layering of movie clips and timeline layers affects code execution order. The rules are as follows:

Use caution when relying on these rules. Layers are mutable, so you should avoid producing code that relies on their relative position. Strive to create code that executes safely without relying on the execution order of the clips in the stack. We can avoid some of the issues presented by the execution stack by keeping all our code on a scripts layer at the top of each code-bearing timeline.



Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.