Controlling movie clip playback

OpenFL use the metaphor of a timeline to convey animation or a change in state. Any visual element that employs a timeline must be either a MovieClip object or extend from the MovieClip class. While OpenFL can direct any movie clip to stop, play, or go to another point on the timeline, it cannot be used to dynamically create a timeline or add content at specific frames; this is only possible using the Flash authoring tool.

When a MovieClip is playing, it progresses along its timeline at a speed dictated by the frame rate of the project. Alternatively, you can override this setting by setting the Stage.frameRate property in Haxe code.

Playing movie clips and stopping playback

The play() and stop() methods allow basic control of a movie clip across its timeline. For example, suppose you have a movie clip symbol on the Stage which contains an animation of a bicycle moving across the screen, with its instance name set to bicycle. If the following code is attached to a keyframe on the main timeline,

bicycle.stop ();

the bicycle will not move (its animation will not play). The bicycle’s movement could start through some other user interaction. For example, if you had a button named startButton, the following code on a keyframe on the main timeline would make it so that clicking the button causes the animation to play:

// This function will be called when the button is clicked. It causes the
// bicycle animation to play.
private function playAnimation (event:MouseEvent):Void {

    bicycle.play ();

}

...

// Register the function as a listener with the button.
startButton.addEventListener (MouseEvent.CLICK, playAnimation);

Fast-forwarding and rewinding

The play() and stop() methods are not the only way of controlling playback in a movie clip. You can also move the playhead forward or backward along the timeline manually by using the nextFrame() and prevFrame() methods. Calling either of these methods stops playback and moves the playhead one frame forward or backward, respectively.

Using the play() method is analogous to calling nextFrame() every time the movie clip object’s enterFrame event is triggered. Along these lines, you could make the bicycle movie clip play backwards by creating an event listener for the enterFrame event and telling bicycle to go to its previous frame in the listener function, as follows:

// This function is called when the enterFrame event is triggered, meaning
// it's called once per frame.
private function everyFrame (event:Event):Void {

    if (bicycle.currentFrame == 1) {

        bicycle.gotoAndStop (bicycle.totalFrames);

    } else {

        bicycle.prevFrame ();

    }

}

...

bicycle.addEventListener (Event.ENTER_FRAME, everyFrame);

In normal playback, if a movie clip contains more than a single frame, it will loop indefinitely when playing; that is, it will return to Frame 1 if it progresses past its final frame. When you use prevFrame() or nextFrame(), this behavior does not happen automatically (calling prevFrame() when the playhead is on Frame 1 doesn’t move the playhead to the last frame). The if condition in the example above checks to see if the playhead has progressed backwards to the first frame, and sets the playhead ahead to its final frame, effectively creating a continuous loop of the movie clip playing backwards.

Jumping to a different frame and using frame labels

Sending a movie clip to a new frame is a simple affair. Calling either gotoAndPlay() or gotoAndStop() will jump the movie clip to the frame number specified as a parameter. Alternatively, you can pass a string that matches the name of a frame label. Any frame on the timeline can be assigned a label. To do this, select a frame on the timeline and then enter a name in the Frame Label field on the Property inspector.

The advantages of using frame labels instead of numbers are particularly evident when creating a complex movie clip. When the number of frames, layers, and tweens in an animation becomes large, consider labeling important frames with explanatory descriptions that represent shifts in the behavior of the movie clip (for example, "off," "walking," or "running"). This improves code readability and also provides flexibility, since function calls that go to a labeled frame are pointers to a single reference—the label—rather than a specific frame number. If later on you decide to move a particular segment of the animation to a different frame, you will not need to change your Haxe code as long as you keep the same label for the frames in the new location.

To represent frame labels in code, OpenFL includes the FrameLabel class. Each instance of this class represents a single frame label, and has a name property representing the name of the frame label as specified in the Property inspector, and a frame property representing the frame number of the frame where the label is placed on the timeline.

In order to get access to the FrameLabel instances associated with a movie clip instance, the MovieClip class includes two properties that directly return FrameLabel objects. The currentLabels property returns an array that consists of all FrameLabel objects across the entire timeline of a movie clip. The currentLabel property returns a string containing the name of the frame label encountered most recently along the timeline.

Suppose you were creating a movie clip named robot and had labeled the various states of its animation. You could set up a condition that checks the currentLabel property to access the current state of robot, as in the following code:

if (robot.currentLabel == "walking") {

    // do something

}

Flash Player 11.3 added the frameLabel event to the FrameLabel class. You can assign an event handler to the FrameLabel instance that represents a frame label. The event is dispatched when the playhead enters the frame.

The following example creates a FrameLabel instance for the second frame label in the Array of frame labels for the MovieClip. It then registers an event handler for the frameLabel event:

var myFrameLabel = robot.currentLabels[1];
myFrameLabel.addEventListener (Event.FRAME_LABEL, onFrameLabel);

...

private function onFrameLabel (e:Event):Void {

    //do something

}

results matching ""

    No results matching ""