| Register
Saturday, May 17, 2008   

Dealing with Dynamic Layers in Flash

Created By  Satori Canton, at  10/14/2004 - 21 comments.

Click to view this author's website.

Many times when creating dynamic effects or especially in Flash video games, you'll find yourself pulling movieclips from the library dynamically, or loading them in from outside .SWFs. These are done using the attachMovie or loadMovie methods. Each of these methods require that you load the new movieclip on a specific layer.


In Flash, everything that appears visually on the screen exists in it's own layer. Say, for example, you had a Flash Asteroids game. If the player ship is on level 10 and you then load a new asteroid into level 10, the player's ship will be removed from the game.


Keeping track of levels can be a simple process if you only have one object attaching movieclips. But in situations where you may have multiple objects managing multiple movieclips, there needs to be an organized way of keeping everything on a unique level.


The technique I use most often is one that I got from Sham Bhangal a few years ago. The technique is basically to set a global variable to a reasonably high number that you know nothing in your movie already exists in (I usually use 10,000 or 100,000) and then every time you need to attach a movie, you call a function that returns that global number and then increments it by one, so the next time you call the function, you get a new unique number. The code I use usually looks like this:


if (globalDepth == null) {
	_global.globalDepth = 100000;
	_global.setDepth = function() {
		return (globalDepth++);
	};
}

I first see if the globalDepth variable is even defined. A few years ago I created a set of components that do a number of text effects, and each component uses this same setDepth function. If you use more than one component at a time, they can end up overwriting your globalDepth, causing the exact problem we're trying to remedy. By checking that for it before writing the variable and the function, we're able to use this same setDepth function in multiple objects, without creating a conflict.


setDepth can also be used when attaching movies by giving each movieclip a unique name (which all movie clips must have). Again, supposing we're creating an Asteroids type game and we need to create a number of asteroids. Assuming that we have a movie in our library with the linkage name "Asteroid," we could populate the game with asteroids with code similar to the following:


asteroidArray = new Array();
for (var i = 0; i < 10; i++) {
	var m = this.attachMovie("Asteroid", "Asteroid" + setDepth(), setDepth());
	m._x = Math.random() * Stage.width;
	m._y = Math.random() * Stage.height;
	asteroidArray.push(m);
}

Here, I'm creating 10 asteroids. The "var m = " is an interesting line. It's not documented, but the attachMovie method in flash actually returns an instance of the movie that was just attached. By assigning it to the variable "m" I can now place the movie in a random location on the stage by simply referring to it as "m."


In the attachMovie method, the first argument is the linkage name of my movie in the library. The second argument is the new name for the movie. Since the movie must have a unique name, I concatenate the result of my setDepth function giving me a unique name for my asteroid. Finally, I use setDepth again to get a unique layer in which the asteroid will exist.


In an actual Asteroids game, you're probably not concerned with the name of an individual asteroid, but you will want to check that your player's ship hasn't hit any of the asteroids. The likely way of managing this is to push the variable "m" into an Array at the end of each loop. This way, we can loop through the array and check for a player collision.


Layers aren't too complicated, but this setDepth function can make life much easier. I find myself writing it almost every time I write a new Flash component.

Need Professional Help For Your ActionScript Project?
ActionScript.com Consulting Services provide top quality professional ActionScript consulting to businesses around the globe. If you have a professional project in need to world-class talent, tell us about your project by requesting a quote today.

Reader Comments

  1. Actionscript Dictionary  Replied:
    ( 10/14/2004 At 11:22 PM)

    MovieClip.getNextHighestDepth()
    Availability
    Flash Player 7.
    Usage
    my_mc.getNextHighestDepth()
    Parameters
    None.
    Returns
    An integer that reflects the next available depth index that would render above all other objects on the same level and layer within my_mc.
    Description
    Method; lets you determine a depth value that you can pass to MovieClip.attachMovie(), MovieClip.duplicateMovieClip(), or MovieClip.createEmptyMovieClip() to ensure that Flash renders the movie clip in front of all other objects on the same level and layer in the current movie clip. The value returned is 0 or higher (that is, negative numbers are not returned).
    For more information, see Managing movie clip depths.

  2. JesterXL  Replied:
    ( 10/15/2004 At 1:44 AM)

    More in-depth documentation (I know, that was bad...):
    DepthManager Overview
    DepthManager on LiveDocs

  3. flashape  Replied:
    ( 10/15/2004 At 2:59 AM)

    flash player 7 has getNextHighestDepth() and getInstanceAtDepth() methods, and I also made a couple that were flash 6 compatible that mimic those:
    http://www.visible-form.com/blog/000039.html
    your method would probably be alittle faster though.

  4. gasi  Replied:
    ( 10/15/2004 At 3:25 AM)

    With Flash MX 2004 or FlashPlayer 7 you've got the new MovieClip method that does exactly what your function does: it's called getNextHighestDepth() and makes your life easier ... your custom function is still very valuable in times where you target < FP 7 ...
    Best regards,
    gasi

  5. Satori Canton  Replied:
    ( 10/19/2004 At 4:09 PM)

    If you are trying to market your services in Flash development, it's important (if not essential) to support Flash Player 6. I should have mentioned that this function is a way of supporting the MovieClip.getNextHighestDepth() in my article.

  6. Edrihan  Replied:
    ( 10/23/2004 At 5:48 AM)

    Wouldn't you want this instead?
    function setDepth() {
    if (dep == undefined) {
    _global.dep = 10000;
    }
    dep++;
    return dep;
    }
    In yours you only return the value if the depth is null. Am I missing something?

  7. Todd Coulson  Replied:
    ( 10/25/2004 At 4:58 PM)

    I just wanted to post this about getNextHighestDepth() command. I recently found it out and think it is important to have it documented here.
    getNextHighestDepth - does not allow for removeMovieClip to work when it is used inside a custom class. This is documented at:
    http://www.macromedia.com/support/flash/ts/documents/remove_mc_depth.htm?pss=rss_flash_19435
    Otherwise, I have used the method a lot and had great success with it. I think this article still has merit too, for those instances where you might still need to use Flash 6 player as your target browser.

  8. Jason Milkins  Replied:
    ( 10/26/2004 At 6:30 PM)

    My prototype for AS1.0 (works with flash6+)
    ---
    MovieClip.prototype.getNextDepth = function() {
    var depth = 0;
    for (var prop in this) {
    if ((typeof this[prop] == "movieclip")||(typeof this[prop] == "object")&&(this[prop].getDepth() != undefined))
    {
    // uncomment the trace to see it working.
    // trace("prop:"+prop+" depth = "+this[prop].getDepth() + " [ Type:"+typeof this[prop] +" ]");
    var newDepth = this[prop].getDepth();
    if (newDepth>depth) {
    depth = newDepth;
    }
    }
    }
    return depth+1;
    };
    usage

  9. boldergezid  Replied:
    ( 11/6/2004 At 1:54 AM)

    Debugging would be easier if the same id was used for both the instance name and its level.
    In your example setDepth() is being called twice,
    and the second time it is already incremented by one.
    In next way every instance name corresponds with the level number,
    and everything still is on a unique level.
    if (globalDepth == null) {
    _global.globalDepth = 100000;
    _global.setDepth = function() {
    return (globalDepth++);

    }
    }
    asteroidArray = new Array();
    for (var i = 0; i<10; i++) {
    var m = this.attachMovie("Asteroid", "Asteroid"+setDepth(), setDepth()+1);
    trace("depth of m ="+m.getDepth());
    trace("instance name =" +m);
    m._x = Math.random()*Stage.width;
    m._y = Math.random()*Stage.height;
    asteroidArray.push(m);

    }
    (credits to Lapo from http://www.gotoandplay.it for noticing)
    boldergeizd

  10. amit  Replied:
    ( 11/9/2004 At 10:06 AM)

    pleaz send me the fla of this depth file

  11. Shahul Shamsudeen  Replied:
    ( 1/9/2005 At 11:30 PM)

    Dear sir,
    I have doubt in Macromedia Flash, I like to load a swf from to another swf file, I never found any problem while loading, but still I want to control the axis where it load, is that possible?
    If u have solution send me the details in sshamsud@rediffmail.com
    bye

  12. boldergeizd  Replied:
    ( 1/23/2005 At 7:08 AM)

    hey, cool.
    i had forgotten about this until I stumbled across
    it browing my bookmarks today.
    this info directly useful in a project i'm working in now.
    boldergeizd

  13. lumberjack  Replied:
    ( 2/4/2005 At 6:45 AM)

    u could even do :
    if (globalDepth == null) {
    _global.globalDepth = 100000;
    _global.setDepth = function(incr) {
    globalDepth+=incr;
    return (globalDepth);
    }
    then:
    var m = this.attachMovie("Asteroid", “Asteroid"+setDepth(1), setDepth(0));

  14. Jez  Replied:
    ( 2/8/2005 At 4:49 PM)

    Has anyone had problems with the getNextHighestDepth() method?
    I don't seem to be able to get anything to stay visible (other than the last item created).
    It's as if getNext... keeps giving the same number.
    Should it be called on _root?

  15. Flash 8.0  Replied:
    ( 2/26/2005 At 7:40 AM)

    hee hee hee!!!
    :)

  16. oie  Replied:
    ( 4/13/2005 At 10:53 PM)

    vaitomar no cu

  17. oie  Replied:
    ( 4/13/2005 At 10:55 PM)

    sun of a bitchs nerds muthers crazys ouchen by now!

  18. ClauÐio  Replied:
    ( 5/1/2005 At 2:38 AM)

    nice function for old players.

  19. Sam  Replied:
    ( 5/31/2005 At 3:17 PM)

    good article

  20. Coder  Replied:
    ( 9/7/2005 At 9:18 PM)

    This is a nice pre-Player7/AS2 function so many thanks.
    You don't need to modify it to get the instance name the same as the level number (messages 9 & 13 above). Just call the function once per new object and use _global.globalDepth for each time you need the number.
    e.g.
    asteroidArray = new Array();
    for (var i = 0; i < 10; i++) {
    setDepth(); //Just once per new movie clip
    var m = this.attachMovie("Asteroid", "Asteroid" + _global.globalDepth, _global.globalDepth); //now the name == the level
    m._x = Math.random() * Stage.width;
    m._y = Math.random() * Stage.height;
    asteroidArray.push(m);
    }
    [Obviously setDepth() could have been left in the attachMovie line as:
    var m = this.attachMovie("Asteroid", "Asteroid" + setDepth(), _global.globalDepth);
    but it's a little easier to read as above]

  21. AM  Replied:
    ( 9/18/2005 At 6:12 PM)

    A conclusive set of global properties are needed in flash, in my opinion most of these classes and managers just confuse the issue. Wouldnt it be better to just set a _depth property which could be implimented on a par with _alpha, _x, _y, _xscale and so on so that i can simply say:
    myclip._depth = x;
    or
    trace(myclip._depth);
    it really seems like the logical solution here?

Login to post your comments. If you do not have an account with us please Register.
Copyright 2005 by ActionScript, Inc.   |  Privacy Statement  |  Terms Of Use  |  ActionScript Client Extranet