Understanding target paths
This is a doubt I come across with very often in the action script board
at
flashkit and I consider that understanding
target paths is fundamental for anyone who starts learning action script.
The first thing to do, when you know you’ll use action script
in your movie (at least in flash MX), is assigning an instance name
to the
object you'll use (button, movie clip or text field).
[this is done by selecting the object and inserting the desired instance
name in the property inspector]
view image
Suppose you have a movie clip on the stage named ball.
Now you can tell it to do something… or set or retrieve one of its
properties e.g.:
x0 = _root.ball._x;//this stores the ball’s x position in
the variable x0
_root.ball._xscale = _root.ball._yscale = 200;//this doubles the size
of the mc
Fine… but what is this _root thing?
_root is the keyword used to refer to the main timeline, or the
stage, or the main movie… as you wish…
If you want to make sure that you have the correct target path, just
use the Insert Target Path button in the actions panel. By selecting the
Absolute (vs Relative) radio button, you’ll see the name of the
movie clip and its target path as a tree.
view image
And what if I have a movie clip inside another? Or even these two, inside
a third one?
Suppose we have blue_ball inside yellow_ball and yellow_ball
inside red_ball.
Clicking the insert target path button in the actions panel, we verify
that we can have three different target paths:
_root.red_ball
_root.red_ball.yellow_ball
_root.red_ball.yellow_ball.blue_ball
This is how you call one instance which is inside another: using
dot notation.
When you use the _root keyword, you’re using absolute
notation.
You can use it from anywhere in your movie: any timeline, any button or
movie clip. And it is always available in the insert target path panel
as long as all the movie clips that contain the movie clip you’re
aiming at, have instance names assigned.
Using absolute notation means that you always go to the main timeline
first, and only after, you go to your destination (possibly, passing through
other mcs).
It is as if you only knew how to get to the beach from your home. If you
leave work and want to go the beach, you’ll have to drive a few
extra miles to go home first.
What about relative notation?
Relative notation lets you go the beach directly!
When you think of relative notation, you think of two keywords:
this and _parent.
In our subject, this will be only a reference to the timeline it
is attached to.
Actually, if you attach the following code to the main timeline
trace(this);//the output is _level0, not _root
or this code to ball:
trace(this);//outputs _level0.ball
trace(this._name);//outputs ball
In the ball example, this is how you use relative notation:
x0 = ball._x;
ball._xscale = ball._yscale = 200;
You can also check this using the insert target path panel with
the Relative radio button selected.
A new keyword appeared: _level0.
_level0 is a reference to the _root of the main movie.
_leveln is a reference to the _root of the movie
loaded at level n (on top of the main movie) using loadMovieNum():
loadMovieNum("external.swf",n);
So you can either use _root or _level0, if you
have only one movie, and want to refer to the main timeline.
Notice that every movie loaded via loadMovieNum() has its own _root.
trace(this) attached to the main timeline of the external.swf,
loaded on _level567 will output _level567.
Going back to the second example, using relative notation - not difficult
to guess - is just:
red_ball
red_ball.yellow_ball
red_ball.yellow_ball.blue_ball
In this example, red_ball is the _parent of yellow_ball and yellow_ball
is the _parent of blue_ball. Also, the _root is the _parent
of red_ball. So _parent is a reference to the timeline uppon which
the current movie clip instace resides
This can be easily verified by attaching a simple trace()
action to each timeline:
trace(_parent);//outputs the full target path, using absolute notation
trace(_parent._name); //outputs the instance name of the _parent movie
clip
You can ascend more than one level up the movie clip hierachy:
The _parent._parent of blue_ball is red_ball and the _parent._parent._parent
of red_ball is the main timeline
Notice that you can’t ascend using the insert target path panel...
Is there a difference between Absolute and Relative notation?
Yes. There is a great difference! Code written using relative notation
is portable, while code written using absolute notation is not!
Suppose you build a movie with some movie clips on the stage, and the
respective code to control them is attached to the main timeline (code
uses relative notation). Then you decide to put all the mcs inside another
mc, all you have to do now is attaching the code to the timeline of the
new mc . This can save you a lot of work!
The most important situation is when you use loadMovie():
empty_mc.loadMovie(“external.swf”);
The external.swf, alone, has its own _root, but when you load
it into empty_mc, there is only one _root! The _root of the main movie.
So, any target path using absolute notation will no longer work!
download .fla: 1
download .fla: 2
Suppose external.swf has a mc called square_mc on the stage
and _root.square_mc.play() is attached to the main timeline.
This works perfecty when the movie plays alone. But once it is loaded
inside empty_mc, its correct target path, using absolute notation becomes
_root.empty_mc.square_mc. So, it would have to be: _root.empty_mc.square_mc.play().
Writing this in the external.swf would be a problem: if you test it alone,
the target path is incorrect!
download .fla: 3
Relative notation works in both situations:
square_mc.play();
download .fla: 4
What about loadMovieNum()?
This is different. Here you specify a level n:
loadMovieNum(“external.swf”, n)
and this _leveln, as tolde before, has it’s own _root,
so, using absolute notation in the external.swf is not a problem. The
target
paths
are always correct.
download .fla: 5
Absolute notation?
If you’re learning, it may be easier… or if you know you won’t
use loadMovie()…
Relative notation?
Is always fine! And makes the code portable. Maybe you have to pay more
attention to avoid mistakes, especially when you can’t use the insert
target path panel…
How do you control a movie clip after using loadMovie()?
Suppose you load external.swf into a movie clip named empty_mc:
empty_mc.loadMovie(“external.swf”);
empty_mc’s timeline, becomes what was the external.swf’s
main timeline.
So, if you want to stop external.swf at a certain time:
empty_mc.stop();
From now on is all the same:
empty_mc.square_mc.play();
Supposing that square_mc is on the stage of the external.swf...
empty_mc.square_mc.rectangle_mc.gotoAndStop(5);
Supposing that rectangle_mc is inside square_mc...
download .fla: 6
To control a movie clip on the stage of the main movie, with code attached
to the main timeline of the external.swf:
_parent.triangle_mc._width = 150;
_root.triangle_mc._height = 150;//absolute
or to define a variable in the main timeline:
_parent._parent.myVar1 = 7;
_root.myVar1 = “loaded”;//absolute
_level0.myVar2 = true;//absolute
download .fla: 7
How do you control a movie clip after using loadMovieNum()?
loadMovieNum(“external.swf”,n);
_leveln.square_mc.play();
_leveln.square_mc.rectangle_mc.gotoAndStop(5);
download .fla: 8
To control the main movie from any level:
_level0.triangle_mc._height = 150;
_level0.myVar = “true”;
In flash MX, thanks to the _global object, there is another great
alternative way to let you use absolute notation:
Attach this code to the main timeline of the external.swf
_global.myTimeline = this;
You define a variable myTimeline that is available from anywhere,
and always points to the _root of the external.swf.
So, if you feel comfortable using absolute notation, all you have to do,
is, instead of _root, using myTimeline. This will also make
your code portable and work perfectly with loadMovie().
A similiar technique is used inside a method, where you would need the
use the this keyword to refer to the timeline, but you can't because
this refers to the object the method applys to:
here = this;
myButton.onRelease = function(){
here._parent.myVar = 5;
};
You can also use variables to replace more complex target paths:
Instead of repeatedly using:
mc1.mc2.mc3.mc4
you can use:
tp = mc1.mc2.mc3.mc4;
tp.play();
tp._width;
tp.someVar = 5;
I think this a good start to help you understand a fundamental concept
of action script.
In this explanation I only used basic actions [like stop() and play()]
and variable definition. I believe the only thing that’s missing
is function definition, but I won’t go further into that, because
it’s exactly the same.
Functions should be defined in the main timeline (but you can define them
on any timeline or movie clip or button), and when you call them, you’ll
have to provide the correct target path to it:
correctTargetPath.myFunction();
There are code samples using functions in the last two .flas.
Hope this helped!
nuno
|