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.