|
|
Controlling movie clip playback
Flash uses 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 ActionScript 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 SWF file. Alternatively, you can
override this setting by setting the Stage.frameRate property
in ActionScript.
Playing movie clips and stopping playbackThe 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.
function playAnimation(event:MouseEvent):void
{
bicycle.play();
}
// Register the function as a listener with the button.
startButton.addEventListener(MouseEvent.CLICK, playAnimation);
Fast-forwarding and rewindingThe 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.
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 labelsSending
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 ActionScript 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 ActionScript code as long as you keep the same label for the
frames in the new location.
To represent frame labels in code, ActionScript 3.0 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
}
Working with scenesIn
the Flash authoring environment, you can use scenes to demarcate
a series of timelines that a SWF file will progress through. Using
the second parameter of the gotoAndPlay() or gotoAndStop() methods,
you can specify a scene to send the playhead to. All FLA files start
with only the initial scene, but you can create new scenes.
Using scenes is not always the best approach because scenes have
a number of drawbacks. A Flash document that contains multiple scenes
can be difficult to maintain, particularly in multiauthor environments.
Multiple scenes can also be inefficient in bandwidth, because the
publishing process merges all scenes into a single timeline. This
causes a progressive download of all scenes, even if they are never
played. For these reasons, use of multiple scenes is often discouraged except
for organizing lengthy multiple timeline-based animations.
The scenes property of the MovieClip class returns
an array of Scene objects representing all the scenes in the SWF
file. The currentScene property returns a Scene
object that represents the scene that is currently playing.
The Scene class has several properties that give information
about a scene. The labels property returns an array
of FrameLabel objects representing the frame labels in that scene.
The name property returns the scene’s name as a
string. The numFrames property returns an int representing
the total number of frames in the scene.
|