00:00
00:00
Newgrounds Background Image Theme

christopher54000 just joined the crew!

We need you on the team, too.

Support Newgrounds and get tons of perks for just $2.99!

Create a Free Account and then..

Become a Supporter!

As3: Display List & Swapping Depths

23,173 Views | 11 Replies
New Topic Respond to this Topic

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.

Response to As3: Display List & Swapping Depths 2007-05-10 00:05:17


At 5/9/07 10:11 PM, ShooterMG wrote: var a:int = getChildIndex( object1 );
var b:int = getChildIndex( object2 );

setChildIndex(object1, b);
setChildIndex(object2, a);

Or you can just use
swapChildren(object1,object2)

or if you want to swap two objects at a certain depth, but you don't know their name... You can use something like:

swapChildrenAt(0,1)

^ Where 0 and 1 are integers specifying the depths of each object.

Cheers :)


Bla

Response to As3: Display List & Swapping Depths 2007-05-10 00:11:02


Hey, it's the journey, not the destination ;)

Response to As3: Display List & Swapping Depths 2007-05-14 18:24:54


At 5/10/07 12:11 AM, ShooterMG wrote: Hey, it's the journey, not the destination ;)

and both paths were awesome.

excellent tutorial. you explained every kind of question i came up with while reading this.


snyggys

Response to As3: Display List & Swapping Depths 2007-05-14 18:49:32


I'd like to add that the display can be an entire tree, not just a simple list - you can manage depths more easily with a technique like this.

// Set up two empty movie clips.

HUDLayer = new MovieClip();
GameLayer = new MovieClip();

// Add them to your stage, or whatever you're using as the main movie clip, so that the HUD's layer is on top of the game's layer.

addChild(GameLayer);
addChild(HUDLayer);

// Now, add some of your custom objects to the layer of choice. All objects in the HUD layer will be on top of all objects in the game layer.

HUDLayer.addChild(new ScoreDisplay());
HUDLayer.addChild(new LivesDisplay());

GameLayer.addChild(new PlayerShip());


BBS Signature

Response to As3: Display List & Swapping Depths 2008-03-07 22:01:33


Here's some code for those of you missing the getNextHighestDepth() function. Keep in mind that if you're just adding an object to the display list, you don't need to do this as it automatically goes to the highest available depth. This is only necessary if you want an object to always stay on top even after it's added to the display list (say, a ship after you add bullets to the stage).

//This goes in an ENTER_FRAME function

if (getChildIndex (box) < numChildren - 1)
{
setChildIndex (box, numChildren - 1)
}

Response to As3: Display List & Swapping Depths 2008-05-15 01:45:50


is there any way to get it not to shift up but to shift down instead?

Response to As3: Display List & Swapping Depths 2008-12-19 13:29:02


At 5/15/08 01:45 AM, oreidoouro wrote: is there any way to get it not to shift up but to shift down instead?

you could just add the new movies on 1

Response to As3: Display List & Swapping Depths 2009-02-21 17:23:05


I may add this to the AS3:Main thread if it were formatted properly -___-

Response to As3: Display List & Swapping Depths 2009-03-11 20:47:56


Is there a way to have something always on the top? I tried putting a really high number in AddChildAt() but it says the index is out of bounds.


If you are reading this then you must be really bored.

BBS Signature

Response to As3: Display List & Swapping Depths 2009-04-18 01:49:55


At 3/11/09 08:47 PM, MrCrinkle wrote: Is there a way to have something always on the top? I tried putting a really high number in AddChildAt() but it says the index is out of bounds.

That's because you can't have empty slots between depths, the highest depth is always

numChildren - 1

Response to As3: Display List & Swapping Depths 2009-05-21 11:03:38


At 5/14/07 06:49 PM, Kinsman wrote: I'd like to add that the display can be an entire tree, not just a simple list - you can manage depths more easily with a technique like this.

// Set up two empty movie clips.

HUDLayer = new MovieClip();
GameLayer = new MovieClip();

// Add them to your stage, or whatever you're using as the main movie clip, so that the HUD's layer is on top of the game's layer.

addChild(GameLayer);
addChild(HUDLayer);

// Now, add some of your custom objects to the layer of choice. All objects in the HUD layer will be on top of all objects in the game layer.

HUDLayer.addChild(new ScoreDisplay());
HUDLayer.addChild(new LivesDisplay());

GameLayer.addChild(new PlayerShip());

I have a problem about this code :

When I draw a background in the FLA file, and use the codes like the above one to add the new MovieClips, the new MovieClips always go behind the backgrounds.

Is there anyway to fix it?