Swapping Depths in AS3 is a frequently requested technique, and it is ridiculously easy to do.
In AS3, there are two components. The Virtual Machine, and the Rendering Engine. You must create objects in both places in order for them to be displayed on the screen. This is not as complicated as it sounds. In fact, it's easier than in AS2.
The rendering engine contains something called a Display List. Each .swf only has one display list, and if you want your object to display in your movie, you must add it to the display list. Only Display Objects can be added to the display list. MovieClip, Sprite, Shape, TextField, etc. are all extensions of the DisplayObject class. Only objects that are extended from this class can be added to the display list.
Firstly, create a new display object:
var mySprite:Sprite = new Sprite();
You have just created a new sprite object. Think of a sprite object as being a MovieClip without a timeline. So now you have your object (pretend we have graphics in it). Just because you created the object, that does not mean it will display in your movie. You must add it to the display list.
addChild(mySprite);
This adds mySprite to the display list. Now your object will be seen on the screen in your movie.
OK, but what about depths? Depths are automatically handled by the rendering engine. When you add a child to a display object container ( i.e. the stage, or other objects that contain display objects), it is adding the object to the next highest depth. So if you have 5 MovieClips on the stage, and you add another one, it will be in position 5 (0 is the lowest position).
A common myth that I am hearing is that you have no control over this. This is false, and I will show you how to control your depths. Say you have 4 MovieClips in the display list.
Score – 3
Enemy – 2
Player – 1
Background – 0
I have listed these clips in the order in which they will appear on the stage. The background, being at position 0, will be underneath everything, whereas the score will be above everything. Now say you want your player to shoot a gun.
addChild(Bullet);
The list would now look like this:
Bullet – 4
Score – 3
Enemy – 2
Player – 1
Background – 0
This is fine and dandy, and perhaps awesome. Less work than attachMovie. Well, what if you want the bullet to appear above all the characters, but have it go behind the score so it doesn’t look weird? AS3 doesn’t let you specify depths.
Wrong. Do this instead.
addChildAt(Bullet, 3);
What this does is it adds the bullet to the display list in the specified index location 3. This causes the existing object at the desired location, and all objects above that location, to be shifted up by one. So this is what the display list would look like:
Score – 4
Bullet – 3
Enemy – 2
Player – 1
Background – 0
Notice the score movieclip is now at index 4. It was shifted up, and it now is displayed on top of everything, so the bullets will go behind it. Nice, huh? So now say you decided that after all of this, you want the Player character to display above the bullets, because he’s invincible to bullets and they should just pass behind him. But how do you change an objects index location once it’s in the display list?
setChildIndex(Bullet, 1);
Doing this will change the bullet’s index value from 3 to 1, causing the object already at index 1 to shift up, along with everything else.
Score – 4
Enemy – 3
Player – 2
Bullet – 1
Background – 0
Fairly simple. But I already know what you’re going to ask next. “But hey, how the heck am I supposed to know the index numbers?” AS3 has a simple method to do this for you. You don’t need to know the index value of the bullet, because that’s the object you are moving. What you need to know is the index value of the spot you are moving the bullet *TO*.
getChildIndex(Player);
This will return the index value of the Player movieclip, which was 1. But how do you actually use this? Like so:
setChildIndex(Bullet, getChildIndex( Player ));
This sets the Bullet to the index that the Player is at, and then shifts the Player and everything else up by one.
So now the moment of truth. To “swap” depths, you use the techniques I have shown you. Here is a simple snippet that you can use in your movies to swap depths between two display objects:
var a:int = getChildIndex( object1 );
var b:int = getChildIndex( object2 );
setChildIndex(object1, b);
setChildIndex(object2, a);
Boom, their depths have been swapped.