控制影片剪辑的方法很多,在ActionScript中最常用和最有用的命令是duplicateMovieClip和attachMovie,它们用于复制和附加影片剪辑,这两个命令可以实现许多效果,如下雪、棋类、射击游戏等。
使用hitTest方法可以代替按钮实现人机交互,从这里也可以看出影片剪辑有多么强大的功能。
startDrag和stopDrag用于对影片剪辑进行拖动,它们可以灵活地实现许多有趣的效果。
7.1 复制和附加影片剪辑
使用ActionScript的一大理由便是它可以极大地提高工作效率,达到事半功倍的效果。本章要介绍的两个命令duplicateMovieClip和attachMovie便是其中的典范。
7.1.1 Array对象
Array对象(动作面板的“对象”/“核心”目录)即数组,它用来记录成组的相关或相似变量。数组中的单个变量称为元素,数组中的每个元素对应一个索引,访问元素需要使用索引,索引需要用方括号括起来。
如下所示的ActionScript创建一个空的数组:
myArray = new Array();
如下所示的ActionScript创建一个确定值的数组并在输出窗口中显示每个元素的值:
weekDay = new Array("SUN", "MON", "TUE", "WED", "TUR", "FRI", "SAT");
for (var i = 0; i<7; i++) {
trace(weekDay[i]);
}
数组中还可以嵌套数组,即构成多维数组,如下所示:
polyArray = new Array();
for (var i = 0; i<3; i++) {
polyArray[i] = new Array(i*3+1, i*3+2, i*3+3, i*3+4);
trace(polyArray[i][0]+" "+polyArray[i][1]+" "+polyArray[i][2]+" "+polyArray[i][3]);
}
输出窗口中将显示:
1 2 3 4
4 5 6 7
7 8 9 10
7.1.2 复制影片剪辑
duplicateMovieClip动作(动作面板的“动作”/“影片剪辑控制”目录)和MovieClip对象(动作面板的“对象”/“影片”目录)中的duplicateMovieClip方法都用于在影片播放时创建影片剪辑的实例,也即复制场景中的父影片剪辑以产生新的影片剪辑。它们和后面要介绍的attachMovie方法对于要在影片中重复产生较多相同图形或动画对象时非常有用,如棋类游戏、射击游戏、鼠标跟随、下雪等特效动画。
要使用duplicateMovieClip动作和MovieClip.duplicateMovieClip方法,首先需要在场景中创建用来复制的父影片剪辑,并且在属性面板中为该父影片剪辑实例命名,该影片剪辑实例名称将作为duplicateMovieClip的参数之一。
在帧动作中使用duplicateMovieClip动作的方法如下所示:
duplicateMovieClip("parentMC", "childMC", 10);
其中,第1个参数parentMC是父影片剪辑的唯一标识符,第2个参数childMC是复制产生的新影片剪辑实例的唯一名称,第3个参数10是新影片剪辑的深度级别(level)。深度级别的概念与层类似,较高深度级别中的图形会遮挡住较低深度级别中的图形,影片剪辑所在的深度级别越高就越贴近我们的视线。在同一个深度级别中只能有一个影片剪辑实例,如果在同一深度级别中添加多于一个影片剪辑实例,新的影片剪辑实例将替换掉旧的影片剪辑实例。
复制产生的影片剪辑实例与父影片剪辑实例的位置是重叠在一起的,所以一般还需要调整新影片剪辑实例的坐标等属性,以使其按照需要显示,如下所示:
_root.parentMC._visible = false;
duplicateMovieClip("parentMC", "childMC", 10);
_root.childMC._x = 275;
_root.childMC._y = 200;
运行以上脚本,屏幕中只能看到新影片剪辑实例,而父影片剪辑实例不见了。从这里也可以看出,父影片剪辑实例的属性并不会影响到复制产生的新实例。
通常情况下,可以用与下面类似的方法复制多个影片剪辑实例:
_root.parentMC._visible = false;
n = 50;
for (i=0; i<n; i++) {
duplicateMovieClip("parentMC", "childMC"+i, 10+i);
_root["childMC"+i]._x = 25+10*i;
_root["childMC"+i]._y = 8*i;
}
在父影片剪辑中使用MovieClip.duplicateMovieClip方法如下所示:
onClipEvent (enterFrame) {
this.duplicateMovieClip("childMC", 10);
_root.childMC._x += 150;
}
它比duplicateMovieClip动作少了第1个参数,即不需要父剪辑名称。如果以上脚本不是在父剪辑而是在别的影片剪辑中,只需要将this换成父剪辑的实例名称即可。
7.1.3 附加影片剪辑
attachMovie方法也是在影片播放时创建影片剪辑的实例,它与duplicateMovieClip不同的是,attachMovie方法不需要使用父影片剪辑,而是将库中影片剪辑的实例附加到场景中。
要使用attachMovie方法,首先需要在库面板中为要附加到场景中的影片剪辑添加链接。为影片剪辑添加链接的方法如下:
(1)在库面板中要添加链接的影片剪辑上单击鼠标右键,在弹出的快捷菜单中选择“链接”命令。
(2)系统弹出“链接属性”对话框,如图7-1所示。

图7-1 “链接属性”对话框
(3)在“链接:”后选中“为动作脚本导出”复选框,“为运行时共享导入”复选框自动变为选中状态,“标识符”文本框变为可用,并将影片剪辑的元件名称作为默认的链接标识符,如图7-2所示。

图7-2 设置链接属性
(4)单击“确定”按钮,添加链接后的库面板如图7-3所示。

图7-3 添加链接后的库面板
为影片剪辑添加链接后,就可以在动作脚本中调用它,如下所示:
attachMovie("blackchess", "chess1", 100);
第1个参数即在库面板中添加的链接名称,第2个参数和第3个参数的意义和使用方法与duplicateMovieClip中相同位置的参数类似。
在使用attachMovie方法将影片剪辑实例附加到场景中后,该实例将默认出现在场景左上角,即坐标原点的位置,所以仍然需要调整它的位置等属性。
7.1.4 删除影片剪辑
通过以上方法创建的影片剪辑实例都可以使用removeMovieClip动作(动作面板的“动作”/“影片剪辑控制”目录)或MovieClip对象的removeMovieClip方法删除,如下所示:
n = 50;
for (i=0; i<n; i++) {
removeMovieClip(_root["childMC"+i]);
}
7.2 练习:动态添加影片剪辑
本例是一个运用了duplicateMovieClip和attachMovie命令的鼠标跟随特效动画,如图7-4所示。
图7-4
本例使用attachMovie命令将鱼附加到场景中的,使用duplicateMovieClip命令复制荷花影片剪辑以调整它的深度级别,使其保持在鱼的上面。
本例源文件如图7-5所示。

图7-5 本例源文件编辑场景
该文件只有两层,图层1用来处理鱼,图层2用来处理荷花。场景中只添加了荷花影片剪辑,它的实例名称与元件名称同为picMC。在库面板中为鱼的身体元件设置了链接,链接标识符与元件名称相同。
(1)在图层1的第1帧添加如下ActionScript:
unit = 20; //鱼的分段数:20
v0 = 12; //鱼的游动速度
v1 = 2/3; //鱼身紧骤程度
v2 = 3; //鱼身大小递减速度
var x = new Array(); //创建横坐标数组
var y = new Array(); //创建纵坐标数组
for (i=1; i<=unit; i++) {
if (i == 1) {
attachMovie("head", "fish"+i, unit+1-i); //在第1节附加鱼头
} else if ((i == 4) or (i == 13)) {
attachMovie("fin", "fish"+i, unit+1-i); //在第4和13节附加鱼鳍
} else {
attachMovie("body", "fish"+i, unit+1-i); //在其他节附加鱼身
}
_root["fish"+i]._xscale = 50-v2*(i-1); //宽度递减
_root["fish"+i]._yscale = 60-v2*(i-1); //高度递减
_root["fish"+i]._alpha = 100-(100/unit)*i; //透明度递减
}
(2)在图层1的第2帧添加如下ActionScript:
x[0] += (_xmouse-x[0])/v0;
y[0] += (_ymouse-y[0])/v0;
for (i=1; i<=unit; i++) {
x[i] = x[i]+(x[i-1]-x[i])*v1;
y[i] = y[i]+(y[i-1]-y[i])*v1;
} //为数组元素赋值
for (i=1; i<=unit; i++) {
_root["fish"+i]._x = (x[i-1]+x[i])/2;
_root["fish"+i]._y = (y[i-1]+y[i])/2;
_root["fish"+i]._rotation = 90+180/Math.PI*Math.atan2((y[i]-y[i-1]), (x[i]-x[i-1]));
} //确定鱼身各节坐标位置和旋转方向
(3)在图层1的第3帧添加如下ActionScript:
gotoAndPlay(2);
该行语句令影片回到第2帧重新确定鱼身各节的位置。
(4)将荷花影片剪辑picMC拖放到图层2,并在属性面板中将其实例命名为picMC。选中该影片剪辑实例,在其动作面板中添加如下ActionScript:
duplicateMovieClip("picMC", "pic", 30);
该行语句复制荷花,并将其深度级别设为30。因为在鱼身各节中,鱼头的深度级别最高,为20,这里只要是一个大于20的数即可将荷花置于鱼的上面。
(5)按Ctrl+Enter测试影片,最终效果如图7-4所示。
7.3 单击影片剪辑
你也许会认为只有按钮才能被鼠标单击,其实并非如此,采用一些技巧,影片剪辑也能接受鼠标的单击动作,并且可以有几种方法实现这种功能。
7.3.1 将按钮置于影片剪辑中
影片剪辑本身并不能响应鼠标单击动作,所以不能像按钮一样使用on(release)或是on(press)等事件处理函数。要使影片剪辑响应鼠标单击动作,可以在影片剪辑中放入按钮。如前一章中的台球实例,在球杆影片剪辑中即加入了一个覆盖整个球杆的隐形按钮,当单击球杆(实际上是单击按钮)时,即令影片剪辑开始播放,执行击球的动作。
7.3.2 hitTest方法
在影片剪辑中加入按钮并不是让影片剪辑响应鼠标动作的唯一方法。事实上,你可以使用onClipEvent (mouseDown)或是onClipEvent (mouseUp)或是onClipEvent (mouseMove)等事件处理函数响应鼠标的动作,如在上一章的scale实例中,我们使用了onClipEvent (mouseMove)事件处理函数。
虽然影片剪辑中有这们的事件处理函数,但它与按钮的事件处理函数是有明显区别的。如影片剪辑的onClipEvent (mouseUp)事件,无论鼠标在什么位置单击,只要是包含该函数的影片剪辑都要执行相应的动作;而按钮的on (release)事件只有当鼠标在按钮上单击才会发生。例如本例文件,其中,为每个影片剪辑添加了如下的ActionScript:
onClipEvent (mouseUp) {
gotoAndStop(2);
}
如图7-6所示,当在窗口中的任意位置单击鼠标时,所有影片剪辑实例都转到第2帧。
图7-6 在窗口任意位置单击鼠标,所有影片剪辑转到第2帧
这是因为所有影片剪辑都响应了mouseUp事件,而不区别鼠标单击的具体位置。
7.3.3 判断哪个影片剪辑被单击
正因为如此,要让影片剪辑像按钮一样准确地响应鼠标动作,就需要判断哪个影片剪辑被单击。
hitTest函数专门用来检测两个影片剪辑之间或影片剪辑和某一点之间是否相交。如将上例影片剪辑中的ActionScript改成如下所示:
onClipEvent (mouseUp) {
if (this.hitTest(_root._xmouse, _root._ymouse)) {
gotoAndStop(2);
}
}
以上语句在mouseUp事件发生时,判断鼠标位置所在点与当前影片剪辑之间是否相交,相交时执行命令gotoAndStop(2)。此时在窗口中单击鼠标,只有鼠标位置处的影片剪辑会转到第2帧,如图7-7所示。
图7-7 鼠标位置处的影片剪辑跳转到第2帧
从例子中可以看出,Flash将影片剪辑所在的最小矩形范围作为影片剪辑的范围,所以在圆形的外切正方形区域单击鼠标同样会使hitTest函数为true。为了使hitTest函数只在圆形范围内为true,可以在hitTest函数中加入一个参数true,如下所示:
onClipEvent (mouseUp) {
if (this.hitTest(_root._xmouse, _root._ymouse, true)) {
gotoAndStop(2);
}
}
现在测试影片,只有在圆形内部单击鼠标,影片剪辑才会响应鼠标动作。
现在已经有两种方法可以使影片剪辑响应鼠标动作,一是在影片剪辑中加入按钮,另一种就是使用hitTest函数,两种方法各有所长,具体使用哪一种要视情况而定。使用hitTest函数会使影片剪辑和库都更精简,而按钮的up、down和over这3种状态对创建交互式的动画也是非常方便和有效的。
7.4 拖动影片剪辑
可以使用startDrag拖动一个影片剪辑,使用stopDrag停止对影片剪辑的拖动动作。
如本例文件,左下角有一只扇动翅膀的蝴蝶。
在蝴蝶上按下鼠标并拖动,蝴蝶会跟随鼠标飞舞;释放鼠标,蝴蝶在当前位置停下。如图7-8所示。按下鼠标拖动蝴蝶用到的ActionScript就是startDrag,释放鼠标停止拖动用到的ActionScript就是stopDrag。
图7-8 使用鼠标拖动蝴蝶
点击浏览该文件
多试几次,你会发现,将蝴蝶拖放到画面中的两朵花上,蝴蝶将不再扇动翅膀,而是静静地品尝花香。这是因为在花朵中央放置了一个透明的影片剪辑,使用hitTest函数判断该影片剪辑与蝴蝶影片剪辑是否相交,如果相交,则让蝴蝶停止在第1帧。
打开文件drag.fla,库中共有两个影片剪辑:蝴蝶和flower。放置两个flower的实例到两朵花的中心,在属性面板中将它们的分别命名为flower1和flower2,并将透明度设置为0%,让它们不可见。
选中蝴蝶影片剪辑实例,打开其动作面板,在其中添加如下ActionScript:
onClipEvent (mouseDown) {
if (this.hitTest(_root._xmouse, _root._ymouse, true)) {
this.startDrag(true);
play();
}
}
onClipEvent (mouseUp) {
if (this.hitTest(_root._xmouse, _root._ymouse, true)) {
this.stopDrag();
}
if (this.hitTest(_root.flower1) or this.hitTest(_root.flower2)) {
gotoAndStop(1);
}
}
在mouseDown事件中,判断是否与鼠标光标相交,如果是,开始拖动。
在mouseUp事件中,判断是否与鼠标光标相交,如果是,停止拖动;并且判断是否与flower1或flower2相交,如果是,停止在第1帧。
该例用到了hitTest函数的两个功能,即判断影片剪辑和鼠标所在点是否相交以及判断两个影片剪辑是否相交。该例还用到了一对很常用的命令:startDrag和stopDrag,使用它们可以方便地实现鼠标拖动操作。
仔细观察将会发现,蝴蝶停在花朵上的位置并不是很居中,这是因为只要两个影片剪辑的边缘相交,hitTest的值就会为true,为了使位置更精确一点,一种方法就是将flower影片剪辑做得更小一点,另一种方法就是修改上面的ActionScript,将判断两影片剪辑相交的一段代码改成如下所示:
if (_root.flower1.hitTest(this._x, this._y, true) or _root.flower2.hitTest(this._x, this._y, true)) {
gotoAndStop(1);
}
实际上,这种方法是将判断两个影片剪辑相交改成判断flower影片剪辑和蝴蝶影片剪辑的中心点相交,范围当然精确得多。
[文章热度:]
上一页:AS 菜鸟教程6 MC属性详解
下一页:AS菜鸟教程8 响应键盘