The Problem
Here's yet another annoying flaw in ActionScript: the gotoAndPlay() statement behaves inconsistently when it is used across timelines -- that is, when you invoke it from within the embedded timeline of a Movie Clip, intending it to affect the main timeline.
Why would you want to do this? Well, consider: buttons are very convenient but you can't alter their properties dynamically through scripting (properties such as size, alpha, and visibility) as you can those of Movie Clips. That's because buttons do not have instance names that can be invoked in scripts. Only Movie Clips have names. So suppose you wanted a particular button to appear only after another button had been clicked. You'd have to mount that button on a Movie Clip whose visibility can be controlled. But if your embedded button is meant to trigger a scene transition in the main timeline, you've got a problem.
Herre's an illustration:
The first button you see above sits in the main timeline. Its script, gotoAndPlay("Scene 2," 1), works just fine; but as we've noted above, you can't easily manipulate this button through scripting.
All three of the remaining buttons are embedded within Movie Clips, meaning that they exist within subsidiary timelines. The first two of these buttons do not work. There's a good enough reason for this: Without modification,the gotoAndPlay() statement always refers to the most local timeline. In the case of Movie Clips, it refers to the Movie Clip's timeline, not the main timeline. Since there is no Scene 2 in the Movie Clip, the statement has no effect; and since Flash is designed to ignore most scripting errors, you see no visible consequence except inaction.You may find books that describe this limitation of ActionScript in absolute terms. James L. Mohler writes in Flash 5: Graphics, Animation, and Interactivity, "the Go To action is limited to jumping to frames and scenes in the current movie [or Movie Clip]." However, this statement is not entirely true.
By using the prefix _parent, you can direct the gotoAndPlay() statement to communicate with at least one timeline not its own -- with some important limitations. You'll see in the third example above that the statement _parent.gotoAndPlay("Scene 2", 1) still doesn't work. This is because those nice folks at Macromedia apparently haven't fully thought through the position of Movie Clips in the object hierarchy.
A Simple Solution
There is a crude but successful work-around for this problem, illustrated in the final example above. While you can't jump scenes from within a Movie Clip, you can jump to a new frame in the main timeline. The number 2 in the successful script does not refer to the scene but rather to the second frame in the main timeline. Armed with this knowledge, you simply need to make that destination frame (frame 2 in our example) a keyframe with an action script that performs the scene transition.
Note that this intermediary keyframe must sit downstream (to the right) of another keyframe that contains a stop() action; otherwise you'll end up in your second scene when your movie starts.
Dealing with Multiple Scenes
The method described above will work if you are trying to script a transition from Scene 1 to some other scene in your movie. If you want to extend this technique to other scenes, however, you need to grasp some complications.
Evidently, in the case of Movie Clips the prefix _parent always refers to Scene 1 of the main movie. That is, all Movie Clips in your project are children of Scene 1, even if they occur in other scenes. So the frame-jumping technique just described will work only if the intermediary frame is in Scene 1.
So what to do if you want to move from Scene 2 to Scene 3; or having arrived at Scene 3, suppose you want to move back to Scene 1? Try this: when your Movie Clip is activated, set a value in a global variable (for instance, _root.togo), then perform some statement such as _parent.gotoAndPlay(2). Understand that the frame 2 to which you refer will always be Scene 1, Frame 2.
In the script for Scene 1, Frame 2, place a simple if table like this one:
if(_root.togo == 1) gotoAndPlay("Scene 1", 1);
if(_root.togo == 2) gotoAndPlay("Scene 2", 1);
if(_root.togo == 3) gotoAndPlay("Scene 3", 1);
The intermediary frame will thus act as a switch, sending you to one scene or another depending on the number you place into _root.togo.
The test file below shows this technique at work. All the clickable objects are Movie Clips that imitate buttons by localizing the mouseDown event. They all set a value for _root.togo and then execute _parent.gotoAndPlay(10), which is where the transition table is scripted.
Source Files
The source files for the examples on this page can be found on Crow: MMShare/gotoProblem/gotoProblem.fla and gotoMultiScenes.fla.
