ActionScript菜鸟基础终极教程3

      电脑技术 2004-10-26 0:1
第4章


影片播放控制



控制影片播放流程的命令有许多,如下所示:
stop:使影片停止在当前时间轴的当前帧中。
play:使影片从当前帧开始继续播放。
gotoAndStop:跳转到用帧标签或帧编号指定的某一特定帧并停止。
gotoAndPlay:跳转到用帧标签或帧编号指定的某一特定帧并继续播放。
nextFrame:使影片转到下一帧并停止。
prevFrame:使影片回到上一帧并停止。
stop命令常常用在帧动作中,以使影片停止并等待用户控制。其他命令常常用在按钮的事件处理函数中。



4.1 使影片停止
最简单的ActionScript恐怕要算stop命令了,当执行stop命令的时候,影片在当前的帧处停止播放。
你可以将stop命令放到时间轴的某一关键帧中,在stop后面需要紧跟一对括号,如下所示:
stop();
执行stop命令时,影片只是暂停在当前帧,在影片中嵌入的影片剪辑或图形元件继续播放,停止的仅仅是主时间轴中的动画。
要让影片继续播放,需要用到ActionScript的另一个命令play。play命令使影片转到下一帧并继续播放。
我们将在按钮部分介绍play命令,下面以一个例子的形式介绍stop命令的使用,其操作步骤如下:
(1)启动Flash MX,在时间轴中插入两个空白关键帧,使时间轴包含3个空白关键帧。
(2)在3个关键帧中使用文本工具分别添加字符1、2、3。
(3)选中第2帧,按F9键打开动作面板,如图4-1所示,在其中添加如下的ActionScript:
stop();

此主题相关图片如下:


图4-1 第2帧和它的动作面板
(4)按Ctrl+Enter测试影片,影片播放到第2帧即停止,你将看不到第3帧。
4.2 跳转到指定帧
另一个基本的ActionScript命令是gotoAndPlay。该命令使影片从当前帧跳转到指定的任意一帧。可以用帧编号或帧标签指定一帧,如下所示:
gotoAndPlay(9);
gotoAndPlay("myFrame");
如果影片中不止一个场景,你也可以指定要跳转到的特定场景的特定帧。如果gotoAndPlay命令中只有一个参数,Flash将认为它代表某个帧;如果有两个参数,第1个参数将作为场景名,第2个参数代表该场景中的帧。如下所示:
gotoAndPlay("myScene", 1);
它表示跳转到场景myScene的第1帧继续播放。
gotoAndPlay命令使影片跳转到某一特定帧并从该帧开始继续播放,如果要使影片跳转到某一特定帧并在该帧位置停止,就应该使用gotoAndStop命令。它的使用方法与gotoAndPlay命令相似,仅仅是跳转帧后执行的动作不同罢了。
还有两个实现跳转帧动作的命令,它们是nextFrame和prevFrame。nextFrame命令使影片从当前位置转到下一帧并停止,prevFrame命令使影片从当前位置转到上一帧(即回退一帧)并停止。它们后面都必须使用括号。
要了解这些命令究竟如何使用,最好的方法就是使用按钮,下面我们就来看看如何创建按钮。
4.2.1 创建按钮
要创建按钮,可以选择“插入”→“新建元件”命令或按快捷键Ctrl+F8,你将看到一个“创建新元件”对话框,在该对话框中你可以在影片剪辑、按钮和图形这3种类型中选择要创建元件的类型。
选择按钮类型,单击“确定”按钮,Flash窗口将由主场景切换到按钮元件的编辑场景。按钮元件的时间轴中有4个帧,分别是弹起(Up)、指针经过(Over)、按下(Down)、和点击(Hit),它们代表了按钮的3种状态和热区(热区的形状代表了按钮能在什么范围内感应到鼠标的动作)。
如果你在按钮的第1帧中放置一个图形,而在其他3个帧中不放置任何东西,那么该按钮的3种状态和热区将是一样的。
要使按钮显示不同的状态,就需要在它的不同关键帧中创建不同的图形或影片剪辑。图4-2显示了一个按钮的4个帧。

此主题相关图片如下:


图4-2 按钮元件的4个帧
完成对按钮的创建后,可以单击舞台上方的场景名“场景1”回到主场景。
按F1或Ctrl+L打开库面板,你将看到库中增加了一个按钮,用鼠标将它拖到舞台中。
4.2.2 为按钮添加脚本
要为按钮添加脚本,首先得选中该按钮,然后按F9键打开动作面板。你也可以在该按钮上单击鼠标右键,在弹出的快捷菜单中选择“动作”命令,这样也可以打开按钮的动作面板。
在专家模式下输入如下脚本:
on (release) {
trace("You are cliking me!");
}
按钮的脚本有特殊的语法,即必须以关键字on开头,以on开头的代码是一种事件处理函数,即当特定事件发生时要执行的代码。在这里,特定事件就是release(松开鼠标),它是按钮最常用的事件。
按钮事件还有press、releaseOutside、rollOver、rollOut、dragOver、dragOut以及keyPress等。press是按下鼠标事件,它在release事件之前发生,releaseOutside是在按钮上按下鼠标,并且在按钮外松开鼠标的事件,rollOver是鼠标指针移到按钮所在热区的事件,rollOut是鼠标从按钮热区移出的事件,dragOver是在鼠标指针位于按钮上方并已按下按钮的情况下,滑出按钮再滑回按钮的事件,dragOut是当鼠标指针位于按钮内部,按下按钮然后滚动出按钮区域的事件,keyPress是按钮响应在键盘上按下某些键时的事件。
某种事件的发生,会触发相应事件处理函数开始运行,上例中使用trace语句将事件信息发送到输出窗口中,使你可以更好地了解具体按钮事件的含义。
4.3 练习:演示文档
用Flash可以实现演示文档的功能,演示文档相当于我们常说的幻灯片,它可以进行逐页展示。如果不使用脚本,Flash动画会很快地播放每一帧,要用Flash制作演示文档就得对Flash添加控制命令。
我们用脚本使每一帧停止,要跳转到别的帧,就需要使用按钮。
制作演示文档的操作步骤如下:
(1)启动Flash MX,编辑前5帧。
(2)在文档中创建5个按钮,从库面板中可以看到它们。
(3)打开主时间轴第1帧的动作面板,其中添加了如下语句:
stop();
影片播放时,会停止在第一帧上。
(4)为图层2的第1帧和第5帧分别添加帧标签begin和end,如图4-3所示。

此主题相关图片如下:


图4-3 第1帧和第5帧的帧标签
(5)选中第1帧中的“开始”按钮,打开其动作面板,在其中添加如下语句:
on (release) {
nextFrame();
}
单击“开始”按钮,停止在第1帧的影片会跳转到第2帧并停止。
(6)分别在第2~4帧的相同位置添加按钮“首页”、“上一页”、“下一页”、“末页”。由于第5帧后面没有别的帧,所以只添加“上一页”和“首页”两个按钮。
(7)为所有“首页”按钮添加脚本:
on (release) {
gotoAndStop("begin");
}
单击“首页”按钮,影片将跳转到帧标签为begin的那一帧并停止,即第1帧。这里也可以用1替代"begin"。
(8)为所有“上一页”按钮添加脚本:
on (release) {
prevFrame();
}
单击“上一页”按钮,影片将从当前帧跳转到前一帧并停止。
(9)为所有“下一页”按钮添加脚本:
on (release) {
nextFrame();
}
单击“下一页”按钮,影片将从当前帧跳转到下一帧并停止。
(10)为所有“末页”按钮添加脚本:
on (release) {
gotoAndStop("end");
}
单击“末页”按钮,影片将从当前帧跳转到帧标签为end的那一帧并停止,在此处也即是第5帧。
(11)按Ctrl+Enter键测试一下影片,单击各个按钮试一下效果。这些添加了ActionScript的按钮是不是变得非常听话?

点击浏览该文件




第5章


控制影片剪辑



影片剪辑是Flash中最重要的一种元件,对影片剪辑的控制是ActionScript的最重要功能之一。从根本上说,Flash的许多复杂动画效果和交互功能都与影片剪辑的运用密不可分。
使用点语法或方括号可以定位影片剪辑。使用方括号时可以使用由变量表示的影片剪辑实例名,这是它相对于点语法的优点。
可以用脚本控制影片剪辑的各种动作,也可以在影片剪辑的事件处理函数中控制主时间轴和别的影片剪辑。影片剪辑最重要的两个事件是load和enterFrame。




5.1 控制影片剪辑的播放动作
设想一个Flash动画,它的主场景中只有一个帧,舞台中只有一个影片剪辑,影片剪辑中并没有ActionScript。如何才能控制影片剪辑的播放动作呢?
要控制一个影片剪辑,首先应该为影片剪辑命名。容易混淆的是,库面板中的影片剪辑本身有一个名称,这里要命名的是场景中影片剪辑实例的名称。它们可以相同,也可以不相同。如果你在场景中创建了同样的影片剪辑的多个实例,那么就需要将每个实例以不同的名称命名,才能用ActionScript对每一个实例进行控制。如果不需要对影片剪辑进行控制,也就不需要为影片剪辑的实例命名。
从本例文件中,你将看到库面板中只有一个影片剪辑rollmc,场景中创建了一个rollmc的实例。你还可以再从库中拖出若干个rollmc的实例将它们放置到场景中。
选中场景中影片剪辑rollmc的实例,打开属性面板,可以看到它被命名为roll,你同时可以看到该影片剪辑原来的名字rollmc,如图5-1所示。你也可以为它指定别的名称,也可以是rollmc,Flash并不会混淆它们之间的区别。

此主题相关图片如下:


图5-1 为影片剪辑实例命名
实例名称可以在程序中用来指代该影片剪辑实例,如果要控制该实例,就需要在脚本中使用该名称。下面,我们就来看看如何通过脚本控制影片剪辑实例roll。
分别选中场景中的4个按钮,打开它们的动作面板,查看其中的代码。
“STOP”按钮:
on (release) {
roll.stop();
}
单击“STOP”按钮使roll实例停止播放。
“PLAY”按钮:
on (release) {
roll.play();
}
单击“PLAY”按钮使roll实例继续播放。
“PREV”按钮:
on (release) {
roll.prevFrame();
}
单击“PREV”按钮使roll实例回退一帧并停止。
“NEXT”按钮:
on (release) {
roll.nextFrame();
}
单击“NEXT”按钮使roll实例播放一帧并停止。
按Ctrl+Enter键测试影片,如图5-2所示。一开始影片剪辑自动播放。单击不同的按钮看看影片剪辑是否执行相应的动作。

点击浏览该文件

图5-2 使用按钮控制影片剪辑的播放动作
除了这几种命令,你还可以使用gotoAndStop或gotoAndPlay命令控制影片剪辑跳转到具体的帧,但是在命令前面都需要指定影片剪辑的实例名称。
这种方法是在影片剪辑实例所在的层级中控制影片剪辑,如果是在影片剪辑内部,要控制它自身的播放,就可以直接使用stop、play等命令,而不需要指定实例名称。如果你在影片剪辑内部的时间轴中使用了名称roll,Flash会在影片剪辑内部的时间轴中寻找该实例。
5.2 定位影片剪辑
我们已经了解了如何使用最简单的方法定位一个影片剪辑,即使用影片剪辑的实例名,后面紧跟一个点记号“.”,然后是你想要影片剪辑执行的命令。
还有许多方法可以定位影片剪辑。首先,我们来看看如何定位Flash影片中不同层级的对象。
Flash影片中最基本的目标层级就是它的主时间轴。可以用关键字_root来表示和定位主时间轴。
例如,你要向主时间轴发送一个gotoAndStop命令,可以使用如下所示的语句:
_root.gotoAndStop(9);
如果这个命令是包含在主时间轴的某一帧上的,则可以省略目标_root。如果这个命令是包含在主时间轴上某个影片剪辑中,需要由影片剪辑来控制它上一级的主时间轴,_root就很有必要了。
通常,要定位包含某一对象的上一级对象,可以使用关键字_parent。所以,如果一个影片剪辑是包含在主时间轴中,在影片剪辑中使用_parent和_root的效果是一样的。如果影片剪辑与主时间轴相差两个层级,即当影片剪辑包含在另一个位于主时间轴中的影片剪辑中,这时在该影片剪辑中使用_parent指代的是它上一级的影片剪辑,而_root是指它上两级的主时间轴。在主时间轴中不能使用_parent,因为主时间轴没有上一级。
可以用数字来方便地说明这种层级关系。主时间轴,它始终是最初级,作为层级0。主时间轴中的一个影片剪辑处于层级1。如果影片剪辑中包含另一个影片剪辑,它处于层级2。对层级2上的影片剪辑来说,_parent指代的就是层级1上的影片剪辑,而不管对哪一级来说,_root始终指代层级0上的主时间轴。
除了用点记号连接_root和实例名,还可以使用方括号表示_root上的对象。对上例中的按钮“STOP”来说,如下所示的3种方法作用是一样的:
rool.stop();
_root.roll.stop();
_root["roll"].stop();
还有一个关键字this,它代表脚本当前所在的层级。如果脚本位于主时间轴中,this即指代主时间轴;如果脚本位于影片剪辑中,this即指代该影片剪辑。所以以上语句还可以用以下两种方式表示:
this.roll.stop();
this["roll"].stop();
使用_root和this时还可以用变量来定位影片剪辑,如下所示:
var mcInsName = "roll";
_root[mcInsName].stop();
今后我们会遇到这种情况,即有roll0~rool99共100个影片剪辑实例,可以使用下面的语句来控制它们:
on (release) {
for (var i = 0; i<100; i++) {
_root["roll"+i].stop();
}
}
多数情况下我们习惯使用_root,但在某些情况下使用this比_root更简便。如要在某个影片剪辑中定位包含 在此影片剪辑中的另一影片剪辑childMC,就可以直接使用this.childMC。
5.3 为影片剪辑添加脚本
现在你已经知道如何向帧和按钮中添加脚本,下面需要知道如何向影片剪辑中添加脚本。
要为影片剪辑添加脚本,首先要选中影片剪辑,再打开它对应的动作面板,然后在其中输入脚本。影片剪辑脚本和按钮的脚本类似,它们都使用事件处理函数,与按钮的on关键字不同,影片剪辑使用onClipEvent关键字。当某种影片剪辑事件发生时,就会触发相应的事件处理函数。
影片剪辑最重要的两种事件是load和enterFrame。
load事件在影片剪辑完全加载到内存中时发生。在每次播放Flash影片时,每个影片剪辑的load事件只发生一次。
在主时间轴停止播放时,影片中的影片剪辑并不会停止播放,这个特性决定了影片剪辑的另一个事件enterFrame的重要性。enterFrame事件在影片每次播放到影片剪辑所在帧时发生。如果主时间轴中只有一帧,且不论它是否在该帧停止,该帧中的影片剪辑都会不断触发enterFrame事件,且触发的频率与Flash影片的帧频一致。
影片剪辑事件的使用方法如下所示:
onClipEvent (load) {
var i = 0;
}
onClipEvent (enterFrame) {
trace(i);
i++;
}
当影片剪辑的load事件发生时,将变量i设置为0。当影片剪辑的enterFrame事件发生时,向输出窗口中发送i的值,然后将i加1。输出窗口中会从0开始输出以1递增的数字序列,直到影片被关闭为止。
为了熟悉影片剪辑事件处理函数的用法,我们来为影片剪辑编写一段简单的脚本,使影片剪辑逆序播放,
我们将从影片剪辑的最后一帧处开始播放,使用prevFrame命令使影片剪辑每次后退一帧。
本例文件场景中有一个影片剪辑元件rollmc,查看一下它的属性面板,并没有为其实例命名,这是因为我们要直接在影片剪辑的动作面板中添加脚本,并不需要用到实例名称。
选中影片剪辑rollmc,此时动作面板的标题栏中应为“动作-影片剪辑”。打开动作面板,其中添加了如下ActionScript:
onClipEvent (load) {
gotoAndStop(40);
}
onClipEvent (enterFrame) {
prevFrame();
}
在事件处理函数onClipEvent (load)中,令Flash影片的播放头转到影片剪辑的第40帧(即最后一帧)。这个事件处理函数只在影片剪辑被加载完成时执行1次。第2个事件处理函数onClipEvent (enterFrame)每播放1帧就执行1次,使影片剪辑回退1帧。
按Ctrl+Enter键测试影片,你将看到齿轮以与上例相反的方向转动,直到影片剪辑的时间轴回到第1帧,prevFrame命令不起作用,影片剪辑停止播放。要让它连续不断的播放,可以在影片剪辑元件rollmc的时间轴第1帧的动作面板中添加如下语句:
gotoAndStop(40);
5.4 用影片剪辑控制别的影片剪辑
一个影片剪辑可以控制别的影片剪辑。综合使用_root或_parent关键字、点符号和影片剪辑实例名称可以将命令发送给另一个影片剪辑实例。例如,在主时间轴上的影片剪辑实例roll1中添加如下脚本以控制同在主时间轴上的影片剪辑实例roll2回退1帧:
_root.roll2.prevFrame();
或者使用方括号表示如下:
_root["roll2"].prevFrame();
如果两个影片剪辑不同在主时间轴上,而是同在别的层级上,可以使用_parent关键字。如果它们不同在一个层级上,也只需要使用点符号逐级标明所在的路径即可。
下面综合运用以上知识实现以影片剪辑控制另一个剪辑的播放动作。
(1)打开本例文件。分别查看场景中的每一层。按Ctrl+L打开库面板。库面板中有三个影片剪辑元件,分别是hour、minute和second。
(2)分别双击每个影片剪辑元件,查看它们的时间轴。
(3)second元件的的时间轴共60帧,secondhand图形元件顺时针旋转1周。在第1帧中添加了如下ActionScript:
stop();
在最后1帧中添加了如下ActionScript:
_root[target].nextFrame();
gotoAndStop(1);
(4)minute元件的的时间轴共60帧,minutehand图形元件顺时针旋转1周。在第1帧中添加了如下ActionScript:
stop();
在最后1帧中添加了如下ActionScript:
_root[target].nextFrame();
gotoAndStop(1);
(5)hour元件的的时间轴共12帧,hourhand图形元件顺时针旋转1周。在第1帧中添加了如下ActionScript:
stop();
(6)回到主场景,在属性面板中为hour影片剪辑和minute影片剪辑指定了与元件名称相同的实例名称。
(7)选中second元件实例,打开其动作面板,其中添加了如下ActionScript:
onClipEvent (load) {
target = "minute";
}
onClipEvent (enterFrame) {
nextFrame();
}
(8)选中minute元件实例,打开其动作面板,其中添加了如下ActionScript:
onClipEvent (load) {
target = "hour";
}
以上脚本的原理是:使每个影片剪辑都在各自的第1帧停止。在second的enterFrame事件中令其自身移到下一帧。直到second元件转动完一周,到达最后一帧,使用_root[target].nextFrame();命令将target所指目标后移1帧,这里的target是在second影片剪辑实例的load事件中定义的,也就是minute。同样,直到minute元件转动完一周到达最后1帧,使用_root[target].nextFrame();命令将target所指目标后移1帧,这里的target是在minute影片剪辑实例的load事件中定义的,也就是hour。
由于影片剪辑的转动是由nextFrame命令实现的,所以在每个元件内部时间轴的最后1帧中添加了跳转到第1帧的语句,避免停止在最后1帧上。
上面的ActionScript主要有两种,一种是在影片剪辑内部时间轴上的帧脚本,另一种是在主时间轴中的影片剪辑脚本。我们使用一个全局变量target记录影片剪辑实例名称,这个动作是在影片剪辑的事件处理函数中完成的,然后将这个全局变量应用到影片剪辑内部的帧脚本中。从这里也可以看到,影片剪辑动作和影片剪辑内部的帧动作是可以进行通信的,全局变量在它们之间有效,但在两个影片剪辑之间就变得无效,所以我们可以在两个影片剪辑中同时使用target而互不影响。
(9)按Ctrl+Enter测试影片,如图5-3所示。


点击浏览该文件





第6章
影片剪辑属性


通过调整影片剪辑的各种属性可以改变影片剪辑的位置和显示状态。_x和_y属性代表影片剪辑在场景中的水平坐标和垂直坐标。_xscale和_width属性决定影片剪辑在水平方向上的显示宽度,_yscale和_height属性决定影片剪辑在垂直方向上的显示高度。使用_rotation属性可以旋转影片剪辑。_alpha属性代表影片剪辑的透明度,_visible属性决定影片剪辑是否可见。使用关键字_xmouse和_ymouse可以获取鼠标光标在屏幕中的坐标位置。

6.1 坐标
Flash场景中的每个对象都有它的坐标,坐标值以像素为单位。Flash场景的左上角为坐标原点,它的坐标位置为0,0,前一个0表示水平坐标,后一个0表示垂直坐标。Flash默认的场景大小为550×400像素,即场景右下角的坐标为550,400,它表示距坐标原点的水平距离为550,垂直距离为400。
场景中的每一点都可以用坐标表示,如图6-1所示标注了若干点的坐标位置。

此主题相关图片如下:

图6-1 场景中的坐标位置示意图
习惯地,水平坐标用x表示,垂直坐标用y表示。在Flash中,分别用_x和_y表示x坐标值属性和y坐标值属性。例如,要在主时间轴上表示场景中的影片剪辑myMC的位置属性,可以使用下面的方法:
myMC._x
myMC._y
如果是在myMC自身的脚本中表示它的坐标,也以使用如下的方法:
_x;
_y;
或:
this._x;
this._y;
在属性面板和信息面板中都有可以查看和更改对象的位置。选择“窗口”→“信息”命令或按快捷键Ctrl+I都可以打开信息面板,如图6-2所示。

此主题相关图片如下:


图6-2 信息面板
信息面板中显示了当前所选图形或影片剪辑的大小、坐标位置、颜色以及鼠标位置等。图6-2中信息面板右边的两个数值框X和Y代表了所选对象的水平坐标和垂直坐标。面板中的 图标表示坐标位置是以所选对象的左上角为基准还是以中心为基本。当前左上角方块呈黑色显示,表示坐标位置以对象左上角为基准,如果中心方块呈黑色显示,表示坐标位置以对象中心为基准。
通过更改_x和_y属性可以在影片播放时改变影片剪辑的位置。如可以为影片剪辑编写如下的事件处理函数:
onClipEvent (enterFrame) {
_x += 5;
_y += 5;
}
该事件处理函数使影片剪辑在每次enterFrame事件中向右和向下移动5像素的位置。
6.2 鼠标位置
你不但可以获得影片中影片剪辑的坐标位置,还可以获得鼠标位置,即鼠标光标在影片中的坐标位置。
表示鼠标光标的坐标属性的关键字是_xmouse和_ymouse,其中,_xmouse代表光标的水平坐标位置,_ymouse代表光标的垂直坐标位置。
需要说明的是,如果这两个关键字用在主时间轴中,则它们表示鼠标光标相对于主场景的坐标位置;如果这两个关键字用在影片剪辑中,则它们表示鼠标光标相对于该影片剪辑的坐标位置。_xmouse和_ymouse属性都是从对象的坐标原点开始计算的,即在主时间轴中代表光标与左上角之间的距离;在影片剪辑中代表光标与影片剪辑中心之间的距离。
多数情况下,你需要用到鼠标光标在主场景中的位置,所以可以使用_root._xmouse和_root._ymouse表示。
你可以使用下面的代码让影片剪辑保持与鼠标位置相同的坐标值:
onClipEvent (enterFrame) {
_x = _root._xmouse;
_y = _root._ymouse;
}
Flash不能获得超出影片播放边界的鼠标位置。这里的边界并不是指影片中设置的场景大小。如将场景大小设置为550×400,在正常播放时能获得的鼠标位置即在(0,0)~(550,400)之间;如果缩放播放窗口,将视当前播放窗口的大小而定;如果进行全屏播放,则与显示器的像素尺寸有关。
6.3 旋转方向
影片剪辑的另一个属性是_rotation。
_rotation属性代表影片剪辑的旋转方向,它是一个角度值,介于-180°~180°之间,可以是整数和浮点数。
_rotation的值始终保持在-180°~180°之间,如果将它的值设置在这个范围之外,系统会自动将其转换为这个范围之间的值。例如,将_rotation的值设置为181°,系统会将它转换为-179°;将_rotation的值设置为-181°,系统会将它转换为179°。
如使用下面的语句实现影片剪辑的连续转动:
onClipEvent (enterFrame) {
_rotation += 10;
}
不用担心_rotation会超出它的范围,系统会自动将它的值转换到-180°~180°之间,并不会影响到影片剪辑转动的连贯性。
6.4 可见性
影片剪辑的另一个属性是_visible,即可见性。_visible属性使用布尔值,即要么为true(1),要么为false(0)。为true表示影片剪辑可见,即显示影片剪辑;为false表示影片剪辑不可见,隐藏影片剪辑。
例如要隐藏影片剪辑myMC:
myMC._visible = false;
6.5 透明度
_alpha(透明度)是区别于_visible的另一个属性,_alpha决定了影片剪辑的透明程度,它的范围在0~100之间,0代表完全透明,100表示不透明。
例如要将影片剪辑myMC的透明度设为50%:
myMC._alpha = 50;
_alpha属性代表了第4种颜色通道,即所谓的alpha通道。前3种颜色通道分别为red(红)、green(绿)、blue(蓝),也就是我们说的三原色通道,通常也简称R、G、B通道。前3种颜色通道决定像素的颜色成份,alpha通道决定像素的透明程度。在计算机中,每种颜色通道都用8 bit(位)来存储,所以如果一幅图像是32位的,它就有所有这4个通道;如果一幅图像是24位的,则它就只有R、G、B这3个通道。
也可以在脚本中设置按钮的_alpha属性。特别指出,将按钮的_alpha属性设置为0,虽然按钮不可见,但是它的热区同样存在,仍然可以对它进行单击等操作;如果要将按钮变为不可用,可以将其_visible属性设置为false。
影片剪辑的不透明状态、_visible=0状态、_alpha=0、50和100时的状态如图6-3所示。

此主题相关图片如下:


图6-3 影片剪辑的不透明状态、_visible=0状态、_alpha=0、50和100时的状态(借林C图,谢谢)
6.6 缩放属性
影片剪辑的缩放属性包括横向缩放_xscale和纵向缩放_yscale。
_xscale和_yscale的值代表了相对于库中原影片剪辑的横向尺寸width和纵向尺寸height的百分比,而与场景中影片剪辑实例的尺寸无关。如库中影片剪辑元件的横向宽度为150,在场景中将它的实例宽度调整为10,在脚本中将_xscale设置为50,则它在影片播放时显示的横向宽度将是150的50%,即75,而不是50像素或10的50%。
当_xscale和_yscale是0~100之间的数时,缩小原影片剪辑;当_xscale和_yscale是大于100的数时,放大原影片剪辑;当_xscale或_yscale为负时,将在缩放的基础上水平或垂直翻转原影片剪辑。
本例文件包含了一个矩形的影片剪辑和一幅图片,并将矩形所在图层作为遮罩层,如图6-4所示。

此主题相关图片如下:


图6-4 将矩形影片剪辑作为遮罩图形
在矩形影片剪辑的动作面板中添加如下ActionScript:
onClipEvent (load) {
xs = _width;
ys = _height;
}
onClipEvent (enterFrame) {
_xscale = 100*(_root._xmouse-_x)/(xs/2);
_yscale = 100*(_root._ymouse-_y)/(ys/2);
}
在load事件中,用变量xs和ys取得影片剪辑初始状态下的宽度和高度值。在enterFrame事件中,计算鼠标位置与矩形影片剪辑中心的距离,算出它与矩形宽度和高度值的比值,然后作为_xscale和_yscale的值。该动画实现移动鼠标位置以改变遮罩效果,如图6-5所示。

点击浏览该文件

图6-5 移动鼠标位置以缩放遮罩层中的矩形
6.7 尺寸属性
上面例子中我们用到了影片剪辑的另两个属性:_width和_height。与_xscale和_yscale属性不同,_width和_height代表影片剪辑的绝对宽度和高度,而不是相对比例。
同样可以使用_width和_height调整影片剪辑的尺寸大小,如上例中的ActionScript也可写成如下所示:
onClipEvent (enterFrame) {
_width = Math.abs(_root._xmouse-_x)*2;
_height = Math.abs(_root._ymouse-_y)*2;
}
Math.abs是一个内置函数,用以计算一个数或表达式的绝对值。因为与缩放属性不同,_width和_height的值不能为负,所以这时使用绝对值函数始终给出一个不为负的值。
此处用更简洁的脚本实现了与上例相同的效果。
6.8 练习:使用影片剪辑的各种属性
本例文件动画效果如图6-6所示。

点击浏览该文件

图6-6 tabalball.fla文件的效果
该动画包含一支球杆影片剪辑stick,一个母球影片剪辑ball。在屏幕中移动鼠标,球杆会跟随鼠标转动,这是利用鼠标位置控制球杆的_rotation属性。球杆的影片剪辑中添加了一个隐性按钮(只有最后1帧作为热区,前面3帧都有为空,所以是不可见的),当单击球杆时,控制球杆影片剪辑向后播放,作回拉动作,再出杆击球。当球杆前端回到球的轮廓位置时,用球杆影片剪辑控制母球影片剪辑,将母球击出,然后将其自身的_visible属性设置为false,隐藏球杆。通过调整母球的_x和_y属性,实现母球的滚动、反弹等动作。在母球滚动时,分析母球位置以判断母球是否落袋,如果母球落袋,则使用trace语句给出提示“bad”,将母球重新置于初始位置。当母球停止滚动时,将球杆的_visible属性重新设置为true,并将球杆的位置设置为与母球相同,等待下一次击球。
球杆stick影片剪辑元件:
(1)在stick影片剪辑元件第1帧的帧动作面板中添加如下语句:
stop();
(2)在第2、10、12帧中添加动作,使球杆作回拉——出杆运动。第12帧时的球杆前端应与中心保持相当于母球半径长度即7.5像素的距离,在此帧时将母球击出。
(3)在第12帧的动作面板中添加如下ActionScript:
_root.motherball.v = 20;
_root.motherball.dir = _root.stick._rotation;
上面的语句为motherball实例传送两个参数值v和dir,v代表了母球的运动速度,dir代表了母球的运动方向,它的方向与球杆的旋转方向相同。
(4)在第13~20帧添加过渡,使球杆击球后在场景中保留一段时间。
(5)在第20帧的动作面板中添加如下ActionScript:
_visible = false;
该语句将球杆自身隐藏。
(6)将第1帧中的球杆转换成按钮,选中该按钮,在动作面板中添加如下ActionScript:
on (release) {
play();
}
单击该钮,球杆往后播放,作击球动作。
球杆影片剪辑实例:
在主场景中将球杆和母球放在左边,将它们的中心对齐。为球杆影片剪辑添加如下ActionScript:
onClipEvent (load) {
_x = _root.motherball._x;
_y = _root.motherball._y;
}
onClipEvent (mouseMove) {
xsm = _root._xmouse-_x;
ysm = _root._ymouse-_y;
if (xsm<0) {
_rotation = Math.atan(ysm/xsm)*(180/Math.PI);
} else {
_rotation = Math.atan(ysm/xsm)*(180/Math.PI)+180;
}
}
Math.atan是Flash的内置函数,用它求一个数或表达式的反正切值。Math.PI是Flash的内置常数,代表圆周率。使用Math.atan计算出的反正切值的单位是弧度,而_rotation属性的单位是角度,所以要将其乘以(180/Math.PI)以实现弧度到角度的转换。
在球杆影片剪辑的mouseMove事件中,根据鼠标位置调整_rotation属性的值,使影片剪辑跟随鼠标转动,这也是鼠标跟随动画中的一种。
母球影片剪辑实例:
在母球影片剪辑实例的动作面板中添加如下ActionScript:
onClipEvent (load) {
v = 0; //初速度
dir = ""; //运动方向
vx = 0; //x方向分速度
vy = 0; //y方向分速度
slow = 0; //加速度
x0 = _x; //初始x位置
y0 = _y; //初始y位置
}
onClipEvent (enterFrame) {
//母球运动中
if ((dir != "") && (slow<100)) {
//母球落袋
if (((_x<60) && (_y<85)) || ((_x>440) && (_y<85)) || ((_x<60) && (_y>265)) || ((_x>440) && (_y>265))) {
_visible = false;
trace("Bad!");
dir = "";
v = 0;
vx = 0;
vy = 0;
slow = 0;
_x = x0;
_y = y0;
_visible = true;
//在母球位置显示球杆
_root.stick._visible = true;
_root.stick.gotoAndStop(1);
_root.stick._x = x0;
_root.stick._y = y0;
}
//撞击球桌左边界
if (_x<60) {
_x = 60;
dir = -(180+dir);
}
//撞击球桌右边界
if (_x>440) {
_x = 440;
dir = 180-dir;
}
//撞击球桌上边界
if (_y<85) {
_y = 85;
dir = -dir;
}
//撞击球桌下边界
if (_y>265) {
_y = 265;
dir = -dir;
}
//调整母球位置和速度
v0 = v*(100-slow)/100;
vx = v0*Math.cos((dir)/(180/Math.PI));
vy = v0*Math.sin((dir)/(180/Math.PI));
_x += vx;
_y += vy;
slow++;
}
//母球减速完毕
if (slow == 100) {
//在母球位置显示球杆
_root.stick._x = _root.motherball._x;
_root.stick._y = _root.motherball._y;
_root.stick._visible = true;
//重置变量
dir = "";
v = 0;
vx = 0;
vy = 0;
slow = 0;
}
}



第7章


影片剪辑方法



控制影片剪辑的方法很多,在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。

点击浏览该文件
源文件:

点击浏览该文件
多试几次,你会发现,将蝴蝶拖放到画面中的两朵花上,蝴蝶将不再扇动翅膀,而是静静地品尝花香。这是因为在花朵中央放置了一个透明的影片剪辑,使用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影片剪辑和蝴蝶影片剪辑的中心点相交,范围当然精确得多



第8章




响应键盘



有4种方法可以检测键盘上的按键动作。第1种方法是使用按钮,第2种方法是使用Key对象,第3种方法是使用键盘侦听,第4种方法是使用影片剪辑的keyUp和keyDown事件处理函数。





8.1 通过按钮检测按键动作
在按钮的on事件处理函数中不但可以对鼠标事件作出响应,而且可以对键盘事件作出响应。如在按钮的动作面板中加入如下所示的代码,在敲击键盘上的A键时输出窗口中将提示:A is pressed。
on (keyPress "a") {
trace("A is pressed");
}
检测键盘上的字母键时,字母都应为小写。如果要检测键盘中的特殊键,如方向键,Flash中有一些专门的代码来表示它们,如表8-1所示。
表8-1 键盘中的特殊键
<Left> <Right> <Up> <Down> <Space>
<Home> <End> <Insert> <PageUp> <PageDown>
<Enter> <Delete> <Backspace> <Tab> <Escape>
如要检测键盘上的<End>键,可以使用下面的ActionScript:
on (keyPress "<End>") {
trace("End is pressed");
}
您可以在一个按钮中加入若干个on函数,也可以在一个on函数中结合多种事件,这使您可以为按钮定义快捷键,如下所示:
on (release, keyPress "<Left>") {
_root.myMC.prevFrame();
}
上面的语句实现单击按钮或按键盘上的左方向键,控制影片剪辑myMC回退1帧。
8.2 影片剪辑的keyUp和keyDown事件
影片剪辑包含两个与键盘相关的事件keyUp和keyDown,使用它们也可以实现对按键事件的响应,如下所示:
onClipEvent (keyDown) {
trace(Key.getAscii());
}
函数Key.getAscii返回与按键相对应的ASCII码。ASCII码是一个整数,键盘上的每个字符对应一个ASCII码,如字母A对应的ASCII码为65,B对应的ASCII码为66,a对应的ASCII码为97, b对应的ASCII码为98,+对应的ASCII码为43等。只有字符才有ASCII码,键盘上的功能键没有ASCII码。
如果需要在输出窗口中输出与按键相对应的字符,可以使用String对象的fromCharCode函数将ASCII码转换成字符,如将上例的trace命令改成如下所示:
trace(String.fromCharCode(Key.getAscii()));
String对象见动作面板的“对象”/“核心”目录下面。
8.3 Key对象
利用按钮检测按键动作很有效,但是并不利于检测持续按下的键,所以不适合于制作某些通过键盘控制的游戏。
这时,您就需要用到Key对象。Key对象包含在动作面板的“对象”/“影片”目录下面,它由Flash内置的一系列方法、常量和函数构成。使用Key对象可以检测某个键是否被按下,如要检测左方向键是否被按下,可以使用如下ActionScript:
if (Key.isDown(Key.LEFT)) {
trace("The left arrow is down");
}
函数Key.isDown返回一个布尔值,当该数中的参数对应的键被按下时返回true,否则返回false。常量Key.LEFT代表键盘上的左方向键。当左方向键被按下时,该函数返回true。
Key对象中的常量代表了键盘上相应的键,如表8-2所示。
表8-2 Key对象中的常量
Key.BACKSPACE Key.ENTER Key.PGDN
Key.CAPSLOCK Key.ESCAPE Key.RIGHT
Key.CONTROL Key.HOME Key.SHIFT
Key.DELETEKEY Key.INSERT Key.SPACE
Key.DOWN Key.LEFT Key.TAB
Key.END Key.PGUP Key.UP
以上是键盘上的功能键,那么如何表示键盘上的字母键呢?Key对象提供了一个函数Key.getCode来实现这一功能,如下所示:
if (Key.isDown(Key.getCode("a"))) {
trace("A is pressed");
}
8.4 键盘侦听
假设在影片剪辑的onClipEvent(enterFrame)事件处理函数中检测按键动作,而影片剪辑所在的时间轴较长,或计算机运算速度较慢,有可能出现这种情况,即当在键盘上按下某个键时还未来得及处理onClipEvent(enterFrame)函数,那么按键动作将被忽略。
还有一个问题就是,在某些游戏(如射击)中,我们需要按一次键就执行一次动作(发射一发子弹),即使长时间按住某个键不放也只能算作一次按键,而Key对象并不能区别是长时间按住同一个键还是快速地多次按键。
在解决这个问题,就需要用到Flash MX中的第3种方法:键盘侦听。when it comes to listening for key presses您可以使用 “侦听器(listener)”来侦听键盘上的按键动作。
要使用侦听器首先需要创建它,您可以使用如下所示的命令来告诉计算机您需要侦听某个事件:
Key.addListener(_root);
Key.addListener命令将主时间轴或某个影片剪辑作为它的参数,当侦听的事件发生时可以用这个参数指定的对象来响应该事件。
上面的代码指定主时间轴来响应该事件。要让主时间轴对该事件作出响应,还需要设置一个相应的事件处理函数。
键盘侦听的事件处理函数有两个:onKeyUp和onKeyDown,如下所示:
_root.onKeyUp = function() {
trace(Key.getAscii());
};
您也可以使用影片剪辑作为侦听键盘的对象,只需要使用影片剪辑的路径代替_root作为Key.addListener命令的参数。
8.5 练习:键盘控制影片剪辑
文件如图8-1所示,可以通过键盘上的方向键控制影片剪辑运动。当敲击空格键时,瓢虫回到初始位置。

点击浏览该文件

图8-1 键盘控制影片剪辑
文件ladybug.fla,其中包含了一个影片剪辑ladybug。在主场景中选中瓢虫影片剪辑,打开其动作面板,其中添加了如下ActionScript:
onClipEvent (load) {
x0 = this._x;
y0 = this._y;
}
onClipEvent (enterFrame) {
if (Key.isDown(Key.SPACE)) {
this._x = x0;
this._y = y0;
this._rotation = 0;
}
if ((Key.isDown(Key.LEFT)) && (Key.isDown(Key.UP))) {
this._x -= 10/Math.SQRT2;
this._y -= 10/Math.SQRT2;
this._rotation = -45;
} else if ((Key.isDown(Key.LEFT)) && (Key.isDown(Key.DOWN))) {
this._x -= 10/Math.SQRT2;
this._y += 10/Math.SQRT2;
this._rotation = -135;
} else if ((Key.isDown(Key.RIGHT)) && (Key.isDown(Key.UP))) {
this._x += 10/Math.SQRT2;
this._y -= 10/Math.SQRT2;
this._rotation = 45;
} else if ((Key.isDown(Key.RIGHT)) && (Key.isDown(Key.DOWN))) {
this._x += 10/Math.SQRT2;
this._y += 10/Math.SQRT2;
this._rotation = 135;
} else if (Key.isDown(Key.LEFT)) {
this._x -= 10;
this._rotation = -90;
} else if (Key.isDown(Key.RIGHT)) {
this._x += 10;
this._rotation = 90;
} else if (Key.isDown(Key.UP)) {
this._y -= 10;
this._rotation = 0;
} else if (Key.isDown(Key.DOWN)) {
this._y += 10;
this._rotation = 180;
}
if (this._x>550) {
this._x = 0;
}
if (this._x<0) {
this._x = 550;
}
if (this._y>400) {
this._y = 0;
}
if (this._y<0) {
this._y = 400;
}
}
当敲击空格键(Key.isDown(Key.SPACE))时,影片剪辑回到初始位置;当敲击不同的方向键或方向键组合时,相应调整影片剪辑的_x、_y和_rotation属性,从而实现以键盘控制影片剪辑。




标签集:TAGS:
回复Comments() 点击Count()

回复Comments

{commentauthor}
{commentauthor}
{commenttime}
{commentnum}
{commentcontent}
作者:
{commentrecontent}