Zones of Depth
In specifying depths for your objects, you need to be
aware of the three "zones" in the ranges of valid depth
values in Flash. Depths themselves, for visual objects,
cannot be less than -16,384 or greater than
2,130,690,045 (there is an exception for
createEmptyMovieClip). Indeed, unusual numbers, but
those are the acceptable values for an object's depth.
No depth will be outside of this range and, as you can
see, Flash starts with the lowest part of that range
when adding objects to the screen when reading the
timeline. Now, within that range there are more or less
3 other ranges. One is the range that Flash uses to
handle the timeline, that being from depths -16,384 to
-1. Following that is the range, 0 to 1,048,575, the
range that specifies the depths at which a movieclip or
textfield can be removed with removeMovieClip() or
removeTextField(), something not possible within the
depths of the previous range. After that range, and
going to the end, 1,048,576 to 2,130,690,04, is a kind
of reserve range where movieclips can be placed by you,
but can't be removed. Respectively I call these ranges,
or zones, timeline, dynamic and reserve:
Zone |
Range |
Note |
Timeline |
-16,384 to -1 |
handled by timeline with Flash, dynamic removal
disabled |
Dynamic |
0 to 1,048,575 |
most dynamically accessible, allows dynamic removal |
Reserve |
1,048,576 to 2,130,690,045 |
overflow - ignored by timeline, dynamic removal
disabled |
The timeline zone of depths is where Flash handles
timeline placed instances, working from around -16384 up
giving plenty of depths before reaching the dynamic zone
at depth 0. These are all based on arrangement specified
in the Flash authoring environment. The very low
starting depth mentioned before, where the lowest clips
in the Flash authoring environment are first placed,
starts at around this lowest depth of -16,384 (usually
-16,383). From there it places objects in sequentially
higher depths until all of the objects on the timeline
are accounted for. Since there are only 16,000 instances
allowed on the screen at one time in Flash, that gives
plenty of depths for Flash to handle those timeline
instances. Now, there's a little more involved here, but
we'll touch upon that a bit later.
Next is the dynamic zone. This represents the range
in which most dynamic instances would be, ideally,
created. After all, intuitively, if Flash asks you to
give a depth for an attached movieclip, you would
consider some reasonable positive number value and
nothing negative or anything too terribly high such as
anything above 1,048,575. This doesn't mean that any
object created dynamically on the screen has to be
within this range. It's just the supposed range for
these clips to exists since it is only within this
range, and this is the important part, that you are
allowed to remove instances with actionscript.
Dynamically created instances, however, can be initially
attached within any valid depth within any of the 3
zones. Should you want to remove them, however, you
would want to place them here. And if not, then you
would have to use swapDepths to place them within this
zone to remove them. Note, this is valid for instances
placed on the timeline as well. Though you may not
initially be able to remove any movieclip you place on
the timeline in the Flash authoring environment, should
you use swapDepths to place that clip in the Dynamic
zone, you are then able to remove it with
removeMovieClip.
The reserve zone kind of makes up what's left. Its
basically just an extension of the dynamic zone with
removal disabled. Objects can be created there or
swapped to a depth within that zone using swapDepths,
but it deems itself unorthodox in that there is no
ability for removal and that the simple value of the
depth seems ridiculously high. Nevertheless, this allows
2,129,641,470 more values of depths to work with when
arranging your objects on the screen through
actionscript giving you a lot of room for playing
around.
The exception to this set of ranges is for the
createEmptyMovieClip method. There is no real limit for
the depth when creating an empty movieclip. You can very
well define it with a depth below -99999999999 or above
999999999999 and Flash will still create the empty clip
despite the fact its out of the 3 valid zone's ranges.
The depth of such an empty clip, however, when set
beyond 2147483647 on the positive side and -2147483648
on the negative, it will start to fluctuate from what
you truly set it, sometimes even being negative if set
at positive and vise versa. You never can tell. It seems
as though this is the absolute range for timeline
instances, -2147483647 to -2147483648, though really
only fully attainable through empty movieclips. Other
clips, such as those within the timeline or created with
something like attachMovie are restricted to the depths
of -16,384 to 2,130,690,045 as laid out in the 3 zones.
The Timeline Refresh
Lets go back to the timeline zone for a moment. There is
something that happens within that range that can cause
a lot of confusion when toying with the depths of clips
there, both dynamic and those placed in the timeline.
What happens is, whenever the timeline is "refreshed"
and all of the instances are redrawn, Flash actually
goes through the depths in the timeline zone and removes
all of the clips which exist within those depths,
whether they were created there through their existence
on the timeline or dynamically with actionscript. Flash
then redraws the screen for those depths based on the
information within the timeline disregarding any
movieclips that might have been placed in those depths
through dynamic means. An example of this kind of
refreshing is caused by using gotoAndPlay to go to a
frame which has already passed; going to frame 5 from
frame 10 for example. When this happens, Flash does this
refresh allowing it to correctly display the screen at
this new frame as the progression of the timeline has
diverted from normal playback and therefore must be
completely re-conceived by Flash.
Obviously, this can cause several problems. One being
the obvious of you losing any dynamically place
instances within that range during a refresh of this
sort, placed there either during their creation or as a
result of swapDepths. What can you do? Well, you can not
put dynamic instances in that range for one.
Alternatively, if you know that you wont run into a
situation where something like that will occur, say a
controlled movieclip consisting of only one stopped
frame, then it can be pretty safe to have clips within
the range of the timeline zone with minimal worry.
Another problem, which may not be so obvious, is that
concerning depth-swapped timeline instances. If you use
swapDepths to bring a movieclip which was placed on the
timeline in Flash out of the timeline zone and into a
depth above 0, then in a timeline refresh, that clip
will not be removed in Flash's clearing of the timeline
instances and a new instance of that clip will be placed
on the screen at its original depth, effectively
duplicating it. Similarly, to avoid this, don't do it.
Again, its safe in controlled timelines, but otherwise,
its risky. Something to be aware of nonetheless.
Kind of along those same lines is the progression of
the Flash timeline from one scene to another. This does
not constitute a timeline refresh, nor, really, any
other particularly special event. Scenes themselves are
only slices of the main timeline which, when the Flash
movie is published, get added on to one another as one
big, single main timeline. Because of this, any dynamic
instance you create (or any instance swapped above 0
depth) in one scene will be present in any other scene
as the timeline plays through them. If you would not
like this to happen, then you would need to use
removeMovieClip/removeTextField to get rid of them at
the end of the scene which they were placed.
Execution Order
Another somewhat overlooked role in depths is their
influence in determining execution order of
ActionScript. Actually, the depths themselves don't
necessarily affect execution order but rather the order
in which instances are created does. However, since
movieclips are created in the order relating to their
arrangement (depth) on the screen, there is that
connection, at least in terms of the timeline. In
regards to actionscript, its more a matter of the order
in which you create any of those instances that you
decide to make. Those you create first (these in the
same timeline) will have their script run before those
you create afterwards. Otherwise, the Flash authoring
environment decides the order of execution based on
arrangement or order created. Oddly enough, for
instances on the timeline, those created last are those
who's enterFrame event scripts get run first.
By default, instances are created from the timeline
starting with the lowest layer upward. This is at the
Bottom Up load order setting in you Publish Settings
options. You have two options for load order, Bottom Up
and Top Down, both which control the order in which
layers are created within Flash. Frame scripts in these
layers are run in the order they are created, so in a
Bottom Up situation, any scripts on lower layers would
be technically run first. However, as mentioned,
enterFrame events are opposite that -and this includes
both onEnterFrame and onClipEvent(enterFrame). In a Top
Down situation, the opposite is true. So, with the
default Bottom Up setting, assuming you have two
movieclips on your timeline, one in a high layer 1 and
the other in a lower layer 2, if both contain an
onEnterFrame event as well as some script in the first
frame of their timeline, then the movieclip in the lower
layer will first have its timeline script run followed
by the timeline script of the movieclip on the higher
layer. Then the enterFrame event of the clip in the
higher layer will run followed by that corresponding to
the lower layer. Note, however, that script order within
the frames of the layers themselves are always run from
top to bottom, so the scripts in higher layers are
always run before the scripts in lower layers. What this
concerns is the execution of scripts within movieclips
themselves as separate objects.
Conclusion
Depths can be a tricky subject. You may be one of those
people who never have any trouble in using them, and
then again, you may be one of those people who have all
the trouble in using them. It all depends on what you
try to do and how accepting Flash is of that. What's
been discussed here pretty much covers all that can and
will go wrong when attempting manipulate depths in
Flash. I think the biggest consideration is the timeline
zone and how it can influence your handling of clips,
both timeline and dynamic. Many of the more common and
unusual troubles experienced with Flash and depths deals
with that range of depths and the repercussions of
putting or removing clips from that zone.
Senocular
Some depth related scripts:
- /* removes any movieclip */
- MovieClip.prototype.killMovieClip = function(){
- this.swapDepths(1048000);
- this.removeMovieClip();
- }
- /* gets the highest or lowest depth in
a movieclip */
- MovieClip.prototype.highestDepth = function(){
- var curr, high = undefined;
- for (var clip in this){
- if (!isNaN(curr = this[clip].getDepth()) &&
this[clip]._parent == this){
- if (curr > high || high == undefined) high =
curr;
- }
- }
- return high;
- }
- MovieClip.prototype.lowestDepth = function(){
- var curr, low = undefined;
- for (var clip in this){
- if (!isNaN(curr = this[clip].getDepth()) &&
this[clip]._parent == this){
- if (curr < low || low == undefined) low =
curr;
- }
- }
- return low;
- }
- /* returns an instance which occupies
the passed depth (if exists) */
- MovieClip.prototype.instanceAtDepth =
function(depth){
- for (var clip in this) if (this[clip]._parent ==
this && this[clip].getDepth() === depth) return
this[clip];
- return undefined;
- }