Page 2. Controlling Clips

Now that we understand some of the pitfalls of accessing the contents of external files, we are ready to start discussing methods for controlling these files. On this page, we will demonstrate a method for loading and unloading external clips in sequence. This is the sort of thing one might want to do to add a "splash screen" to a video or a summary/assessment screen to the end of a set of exercises. By approaching this with external files, we will attain a high level of extensibility as we shall see in the final product for these tutorials.

For this page, we will use the following three clips to be loaded from the same directory in which our managing fla file resides. The thumbnail versions below show the individual behaviors of these clips. Each uses pure timeline-based animation with no ActionScript added. If you are curious about the structure of these clips, the source fla files are available at the bottom of this page.

clip0.swf
clip1.swf
clip2.swf

The following code defines an array of file names to be used and an integer called index that will represent which of these files is the next one to be used. The loading of files is done as it was on page 1 of this tutorial with a few small differences. You will notice that the file name for the URLRequest object is now a reference to our clips array. In addition, you will notice that we add the initially empty MovieClip to the stage at the outset so that when it is "removed" in the first line of the nextClip function we avoid a runtime error. Finally, this example points out that the function called when the INIT event fires can be generic so that the same function suffices for each load method call. In general, we can avoid constructing multiple Loader objects if we make this function generic and remember to unload content after we are finished with it.

 

// Array of external clips to use. Variable index refers to next clip to be displayed.

 

var clips:Array = ["clip0.swf", "clip1.swf", "clip2.swf"];

var index:int = 0;

 

 

// Stuff for loading files

 

var thisLoader:Loader = new Loader();

thisLoader.contentLoaderInfo.addEventListener(Event.INIT, doneLoading);

 

var thisMC:MovieClip = new MovieClip();

stage.addChild(thisMC); // Add empty MC initially so the nextClip function works even on first call

 

 

// Gets the next MC, waiting for INITialization before adding it to the stage

 

function nextClip():void {

thisLoader.load( new URLRequest(clips[index]) );

}

 

 

// Remove old clip, tell AS that the loaded file is the new one, add it to the stage, and play.

 

function doneLoading(e:Event):void {

stage.removeChild(thisMC);

thisMC = MovieClip(thisLoader.content);

thisLoader.unload();

stage.addChild(thisMC);

thisMC.gotoAndPlay(1);

}

 

 

// "Next button" calls a nextClip and increments index mod the number of files in the list

 

btnNext.addEventListener(MouseEvent.CLICK, playNext);

 

function playNext(e:MouseEvent):void {

nextClip();

index = (index + 1)%(clips.length);

}

 

The code above (along with a button and label created on the stage) results in the behavior shown below:

Download

  • Flash CS3 file manager2.fla is the final functioning file shown above.
  • The Flash Player files clip0.swf, clip1.swf, and clip2.swf is required to be in the same directory as the manager2.fla file.
  • If you want to see the source code for these little clips, the Flash CS3 files clip0.fla, clip1.fla, and clip2.fla contain the the timeline-based animations used in these examples.

Notes

  • In this example, we are not taking full advantage of the fact that each loaded clip can be a fully functional Flash player file, complete with all of the user interaction we know how to construct. This example is well-suited to slide-show like effects, but we will use more interesting external clips in our final application in this tutorial.

Automatically loading the next clip

It is not completely obvious how to monitor the progress of the loaded clips from the managing movie, so we include an example here to illustrate the idea. Unlike a video or a sound, there is no conventional sense in which an external movie clip has finished playing since the looping behavior evident in the first examples on this page implies that the movie is never finished. Certainly the clip could be created in the first place to stop after one play through, but we continue to assume that our external swf files are already built and contain no ActionScript code at all. We will address direct communication from child to parent in our final application.

Even if the clip is in this permanent looping mode, we can tell when it has played through once by referencing its totalFrames and currentFrames properties. These properties are exactly what they sound like. If we simply check when currentFrame is equal to totalFrames as the clip is playing, we can stop the play automatically and move on to the next clip. To be sure we don't miss this happening, we will listen for this to happen every time the managing movie hears the ENTER_FRAME event. Since the frame rate of the child clip is forced to match the frame rate of the parent clip, it is impossible for currentFrame to skip over totalFrames between the moments when we check.

We accomplish this by adding a listener to the stage at the beginning of the script that will (via the function runOnce) be continually comparing currentFrame to totalFrames in the currently loaded clip. When these are equal, the playNext function is called, thus removing the old clip and loading the new one. You will notice that we have also rearranged the playNext function below to accommodate being called automatically when the managing movie starts. In this case

Replace the block of code above starting with the definition of the doneLoading function with the following code, and you will accomplish the final behavior we are looking for. (Note that the doneLoading function has just one additional line of code in order to monitor the loaded clip to detect when it has finished running.)

 

function doneLoading(e:Event):void {

stage.removeChild(thisMC);

thisMC = MovieClip(theLoader.content);

theLoader.unload();

thisMC.addEventListener(Event.ENTER_FRAME, runOnce);

stage.addChild(thisMC);

thisMC.gotoAndPlay(1);

}

 

 

// When thisMC has finished, play the next clip.

 

function runOnce(e:Event):void {

if (thisMC.currentFrame == thisMC.totalFrames) {

thisMC.removeEventListener(Event.ENTER_FRAME, runOnce);

index = (index + 1)%(clips.length);

nextClip();

}

}

 

 

// Call the nextClip function initially to get the ball rolling

 

nextClip();

 

The following applet shows the results of making this change as well as deleting the (now pointless) "Next button" from manager2.fla.

Downloads

Notes

Back to Intermediate Tutorials              Back to Flash and Math Home

We welcome your comments, suggestions, and contributions. Click the Contact Us link below and email one of us.

Adobe®, Flash®, ActionScript®, Flex® are registered trademarks of Adobe Systems Incorporated.