控制影片剪辑播放

Flash Player 9 和更高版本,Adobe AIR 1.0 和更高版本

Flash 利用时间轴来形象地表示动画或状态改变。任何使用时间轴的可视元素都必须为 MovieClip 对象或从 MovieClip 类扩展而来。尽管 ActionScript 可控制任何影片剪辑的停止、播放或转至时间轴上的另一点,但不能用于动态创建时间轴或在特定帧添加内容,这项工作仅能使用 Flash 创作工具来完成。

MovieClip 在播放时将以 SWF 文件的帧速率决定的速度沿着其时间轴推进。或者,您也可以通过在 ActionScript 中设置 Stage.frameRate 属性来覆盖此设置。

播放影片剪辑和停止播放

play() stop() 方法允许对时间轴上的影片剪辑进行基本控制。例如,假设舞台上有一个影片剪辑元件,其中包含一个自行车横穿屏幕的动画,其实例名称设置为 bicycle 。如果将以下代码附加到主时间轴上的关键帧,

bicycle.stop();

自行车将不会移动(将不播放其动画)。自行车的移动可以通过其他某种用户交互来开始。例如,如果您有一个名为 startButton 的按扭,则主时间轴上某一关键帧上的以下代码会使单击该按扭时播放该动画:

// This function will be called when the button is clicked. It causes the  
// bicycle animation to play. 
function playAnimation(event:MouseEvent):void 
{ 
    bicycle.play(); 
} 
// Register the function as a listener with the button. 
startButton.addEventListener(MouseEvent.CLICK, playAnimation);

快进和后退

在影片剪辑中, play() stop() 方法并非是控制播放的唯一方法。也可以使用 nextFrame() prevFrame() 方法手动向前或向后沿时间轴移动播放头。调用这两种方法中的任一方法均会停止播放并分别使播放头向前或向后移动一帧。

使用 play() 方法类似于每次触发影片剪辑对象的 enterFrame 事件时调用 nextFrame() 。使用此方法,您可以为 enterFrame 事件创建一个事件侦听器并在侦听器函数中让 bicycle 回到前一帧,从而使 bicycle 影片剪辑向后播放,如下所示:

// This function is called when the enterFrame event is triggered, meaning  
// it's called once per frame. 
function everyFrame(event:Event):void 
{ 
    if (bicycle.currentFrame == 1) 
    { 
        bicycle.gotoAndStop(bicycle.totalFrames); 
    } 
    else 
    { 
        bicycle.prevFrame(); 
    } 
} 
bicycle.addEventListener(Event.ENTER_FRAME, everyFrame);

在正常播放过程中,如果影片剪辑包含多个帧,播放时将会无限循环播放,也就是说在经过最后一帧后将返回到第 1 帧。使用 prevFrame() nextFrame() 时,不会自动发生此行为(在播放头位于第 1 帧时调用 prevFrame() 不会将播放头移动到最后一帧)。以上示例中的 if 条件将检查播放头是否已返回至第一帧,并将播放头设置为处于最后一帧前面,从而有效地使影片剪辑向后持续循环播放。

跳到不同帧和使用帧标签

向新帧发送影片剪辑非常简单。调用 gotoAndPlay() gotoAndStop() 将使影片剪辑跳到指定为参数的帧编号。或者,您可以传递一个与帧标签名称匹配的字符串。可以为时间轴上的任何帧分配一个标签。为此,选择时间轴上的某一帧,然后在属性检查器的“帧标签”字段中输入一个名称。

当创建复杂的影片剪辑时,使用帧标签比使用帧编号具有明显优势。当动画中的帧、图层和补间变得很多时,应考虑给重要的帧加上具有解释性说明的标签来表示影片剪辑中的行为转换(例如,“离开”、“行走”或“跑”)。这可提高代码的可读性,同时使代码更加灵活,因为转到添加了标签的帧的 ActionScript 调用是指向单个引用(即“标签”,而不是特定帧编号)的指针。如果您以后决定将动画的特定片段移动到不同的帧,则无需更改 ActionScript 代码,只要将这些帧的相同标签保持在新位置即可。

为便于在代码中表示帧标签,ActionScript 3.0 包括了 FrameLabel 类。此类的每个实例均代表一个帧标签,并具有一个 name 属性(表示在属性检查器中指定的帧标签的名称)和一个 frame 属性(表示该标签在时间轴上所处帧的帧编号)。

为了访问与影片剪辑实例相关联的 FrameLabel 实例,MovieClip 类包括了两个可直接返回 FrameLabel 对象的属性。 currentLabels 属性返回一个包含影片剪辑整个时间轴上所有 FrameLabel 对象的数组。 currentLabel 属性返回一个字符串,该字符串包含在时间轴上最近遇到的帧标签的名称。

假设创建了一个名为 robot 的影片剪辑并已经为其动画的各个状态加上了标签。可以设置一个用于检查 currentLabel 属性的条件以访问 robot 的当前状态,如下面的代码所示:

if (robot.currentLabel == "walking") 
{ 
    // do something  
}

Flash Player 11.3 和 AIR 3.3 向 FrameLabel 类中添加了 frameLabel 事件。您可以向表示帧标签的 FrameLabel 实例分配事件处理函数。在播放头进入帧时调度事件。

下面的示例为 MovieClip 的帧标签数组中的第二个帧标签创建 FrameLabel 实例。然后它为 frameLabel 事件注册事件处理函数:

var myFrameLabel:FrameLabel = robot.currentLabels[1]; 
myFrameLabel.addEventListener(Event.FRAME_LABEL, onFrameLabel); 
 
function onFrameLabel(e:Event):void { 
    //do something 
}

使用场景

在 Flash 创作环境中,您可以使用场景来区分 SWF 文件播放时将要经过的一系列时间轴。使用 gotoAndPlay() gotoAndStop() 方法的第二个参数,可以指定要向其发送播放头的场景。所有 FLA 文件开始时都只有初始场景,但您可以创建新的场景。

使用场景并非始终是最佳方法,因为场景有许多缺点。包含多个场景的 Flash 文档可能很难维护,尤其是在存在多个作者的环境中。多个场景也会使带宽效率降低,因为发布过程会将所有场景合并为一个时间轴。这样将使所有场景进行渐进式下载,即使从不会播放这些场景。因此,除非是组织冗长的基于多个时间轴的动画,否则通常不鼓励使用多个场景。

MovieClip 类的 scenes 属性返回表示 SWF 文件中所有场景的 Scene 对象的数组。 currentScene 属性返回一个表示当前正在播放的场景的 Scene 对象。

Scene 类具有多个提供有关场景信息的属性。 labels 属性返回表示该场景中帧标签的 FrameLabel 对象的数组。 name 属性以字符串形式返回场景的名称。 numFrames 属性返回一个表示场景中帧的总数的整数。