难度: 中级
软件环境: Flash 5
可以告诉我,你读了多少篇我写的路径教程?嗯,一点点吧。如果将你所学的知识模块化,并可以随时随地用你所学,那不是很好?当然,手工输入的路径并不是精辟的脚本。所以我们今天要更进一步,学习真正的路径。
动态路径(数组标识方法)
假定你写了一段高级脚本,用来复制若干个movie clip,并将它们随机放置在舞台上。做得不错!现在我希望你浏览一下你的脚本,并让他们精简一半。”我可以做到”你边说着,边写代码:
_root.duplicate1._xscale = 50;
_root.duplicate1._yscale = 50;
_root.duplicate2._xscale = 50;
_root.duplicate2._yscale = 50;
_root.duplicate3._xscale ...
已经开始无聊了吧?我知道我会。当然,我们不希望为这累人的活写上若干条代码。如果你读过循环教程,你就会知道这样的例子用循环语句相当合适了。下面是改用循环语句写的代码:
for (var j=0; j<x; j++) {
_root.duplicate ... oh oh
果真如此吗?我们都知道你想复制若干次……但是如何告诉Flash知道呢?好,现在你可以用动态路径来解决。在Flash 4里,当我们想计算一个动作或程序的结果时,我们使用eval()函数。今天,我们要使用方括号( [ ] )。你我都认识这些括号:我们在使用数组的时候用到它们。事实上,动态路径与访问数组中的对象两者异不大。想法就是我们赋予Flash一个基准的时间线, 用它来寻找元素,这些元素的名字是从那些一个或更多未知的单元组合起来的(变量、数学运算结果等等)。在上面例子中,我们的变量j声明了当前我们希望应用效果的复制品。我们也知道那些复制品的名字是以duplicate1、duplicate2这样的格式。所以我们就需要告诉Flash将数字i连接到字符串”duplicate”后面。别担心,很容易的,让我们来看看例子。
for (var j = 0; j<x; j++) {
_root["duplicate"+j]._xscale = 50;
}
我想这段代码大部分样子,你先前是见过的。For循环你是知道的,第二行最后的点符号也很熟悉,但是第二行的前面部分,有点生疏,好,我现在来解释一下。简而言之,它告诉Flash:”注意_root时间轴上的对象,它的名字是由字符串”duplicate”与连接在其后的数值i组成”。注意,在_root与左方括号之间缺了一个点;这不是语法错误,这是正确的动态路径格式。另外注意,在右方括号后面有一个点,是你所期待的标准路径。
还不错吧!对这类事情例子总是有用。还是让我们来看更多的内容吧。我们有一个输入框(变量输入),你想让movie clip的实体名称出现在此框内。
_root[input]._visible = false;
对于开始阶段,这个例子可能简单了些。这段代码是尽量简单地告诉Flash来计算变量input,然后用此来创建对象的路径。当然,这儿有些难(但很有用)。现在你有一大批movie clip实体名称,并且你想给每个_x设定一个随机数。
_root.nameArray = [ Joe , Jenny , Jesse , Jumping-Jude ];
for (var j=0;j<_root.nameArray.length;j++) {
_root[_root.nameArray[j]]._x = random(200);
}
很明显这里有些难度,但这是个速成班,所以你不得不学得快些!再注意这个明确的字串_root.nameArry好像并不必要。你可以简单的用nameArry,但我还是愿意保留我明确的路径以备以后调试。同样要注意的是,你必须在动态路径里包括_root;在被指向时Flash至少需要时间轴的名称。
数组标识与动态路径用法有一些复杂。实践是最好的学习方法,所以你可以给自己一些小课题来增加你的经验!一旦你对此着迷,我们就继续前进。
相对路径
这个图表是从我先前的路径教程中借用的。在初级教程中,我们讨论了路径如何可以用树状结构关联。树的主干就是movie clips(分支)所在的_root主时间轴,每个分支可以容纳其他clip和对象(子分支),每个子分支可以包含变量(叶子)。假设我们现在要在clip2里键入一些代码来调用clip1里的一个变量。用初级教程中所教授的方法,代码就是这样的:_root.clip1.variableName = value;
好极了!但是如果这个SWF被载入其他SWF中呢?在被载入到一个movie clip中时(我们使用loadMovie(“file.swf”,”targetMC”),所有的路径都会被改变!Clip1的路径不再是_root.clip1而是_root.targetMC.clip1。的确我们可以仔细检查并重新写路径,但这就意味着没有被载入其他SWF中时,我们的代码就无法运行。我们想要的是那种不受外部环境影响,独立执行的代码。
相对路径可以帮我们完成心愿。假设我们在楼梯上。我说“向上三级”,你照做。我说“走到第二级台阶”。你会先返回到底楼,然后从底层开始往上走吗?不,你很懒,只会向下移一级台阶。这就是我们想让Flash做的事情。我们不想让它走到路径的底层,因为情况随时在变,我们只希望它知道与它相关的事情。Flash有一些代码结构允许我们访问与当前时间轴相关的变量时间轴。最重要的两个是this 与 _parent。
this 是指向当前活动的对象或时间轴的。比如,如果我打开一个新的Flash文件,并在主时间轴的第一帧上加上下面的代码:
this.variable = value;
Flash会创建出一个新的_root级别的变量,并赋予值。如果我在一个Movie clip里键入同样的代码,该变量就会被创建在movie clip的时间轴上。“那又怎么样?”你说,“你只需变量名而可以省略this”。并不完全正确。你可以省略this,但Flash需要它。ActionScript是个非常友好的语言,它允许你懒惰,或者一定程度上犯点小错。如果你省略this命令,Flash的ActionScript编译器会在编译时自动加上,以使代码适合Flash播放器阅读。此外,this有更高价值的应用,尤其对高级程序员。它允许你创建你自己的函数原型,并在对象之上运行函数。在with 或 tellTarget命令里面它也非常有用。这时候,你只需记得它是指向当前活动的时间轴或对象的就行了。
现在该讲_parent了。
刚开始,_parent的用途可能更明显。再看一下左边图表,回忆下类似的台阶。我们知道台阶2是台阶3住前一级的台阶。所以clip 1对clip 2来说,就是往上一级;就是说clip 2是在clip 1的时间轴上。因此Clip 1称为clip 2的parent (父)。于是,当我们想从clip 2里指向clip 1时,我们不需要给出从_root开始的全部路径,而只需用相对路径:
_parent.variable = value;
明白了吗?主时间轴(_root)是clip 1的parent。所以如果我们在clip 1里面,并想指向主时间轴上的某些元素时,我们就可以用:
_parent.variable = value;
当然,在这个例子里我们没有为了节省字母写成_root.variable,而是用_parent.variable。再回忆一下loadMovie例子,如果我们使用_root表示将此SWF载入一个movie clip里,这样的表示法看起来好像被载入的SWF是在_root上面。使用_parent语法,我们就可以确保它看上去是在其parent时间轴上的变量。
_parent参数是可以叠加的。所以当我们在clip 2上,希望跳两级到主时间轴上时,我们可以使用:
_parent._parent.variable = value;
第一个_parent使我们从clip 2跳到clip 1里面,第二个使我们从clip 1跳到主时间轴上(再说一次,在这个例子里可以是_root,但在loadMovie例子里可能会完全不一样)。
的确如此。孩子们,要想成为高手,实践是最好的方法!