gotoAndPlay and the queue
http://ericlin2.tripod.com/goto/gotoAndPlayt.html ?"gotoAndPlay" is the oldest actionscript command in the history of Flash. It moves the playhead to another frame. However,the effect can be very complex because it interrupts the natural sequential order of playing. Two major side effects occur behind the scene - execution of frame scripts and unloading/loading of the child movieClips.? Also it is important to know the queue structure that handles frame script. I would first explain the process of normal playing and then explain this script driving playhead movement. Later I will put several quiz and example to demonstrate the concept. I was told by DVD vender that to move DVD playhead to-and-fro vigorously might cause damage to the machine. In fact,for Flash,we are not so crazy to move this and that playhead here and there. Most of the time,our gotoAndPlay script is so simple as demonstrated in the quiz. Fully understanding about the details behind the scene is just "academic". Normal playing For each interval,Flash does these jobs:
When the movie starts,the stage is empty. No active clips on the stage. All clips are debut clips. So,the whole job is to do initialization. The _root and all the clips are initialized by putting the frame 1 script on to the queue. The initialization starts from _root to clips with nest structure. So,the queue would like this:
After an interval,Flash starts to play. If the playMode of the main timeline is "play",then it should now play frame 2. Lets assume that mc2 is no more present and a new subClip appears when mc1 plays to frame 2,then the queue would be like this:
The initialization is always start from _parent to child. However,the playing of active clip (onEnterFame function and current frame script) starts from the last clip that are newly added. So,the sequence of onEnterFrame seems to be child to _parent. Usually,the initialization also adds the playing roll from top layer down. But,layering is not necessarily the sequence of adding members if we consider loading and unloading. Anyway,the playing contains paired onEnterFrame/frame script ordered by child-> _parent relationship and some debut initialization frame 1 script ordered by _parent -> child relationship. The queue I mentioned several times about "queue" . What is that ? Most procedures or processes use stack. When a procedure calls another subProcedure,it pushes present process point into a stack and the subProcedure will be executed first till it returns. Then the process pop the process point from the stack to continue unfinished part of the mian procedure. However,gotoAndStop/gotoAndPlay does not follow this rule. The command gotoAndStop/gotoAndPlay moves the playhead which evokes frame script of destine frame. The frame script is put to the end of the queue waiting for execution. The current frame script continues till the end and then pickup the next elements in the queue. Anyway,at last,the evoked frame script in the queue will get its turn. For example: _root.frame 1 contains a command "_root.gotoAndStop(2) and mc.gotoAndStop(3); Then the initial queue by the natural playing will be:
Before Flash renders the graph,it need to run the queue. When the first element of the queue runs,the _root.gotoAndStop(2) moves the playhead of the _root to frame 2 and evokes the frame script of frame 2. Also,"mc.gotoAndStop(3)" moves the playhead of the mc to frame 3 that evokes the frame script of the mc. Instead of executing those frame script immediately,they are put to the queue. The result is :
The 3rd line and 4th lines will be executed after the 2nd line. This is queue. It is queue not stack. Sometimes this turns out very awkward and confusion. However,it ensures that each frame script be executed without interruption. It is more safe by avoiding the crash from interrupted calls. The command "mc.gotoAndStop(2)" The command moves the playhead of mc to destine frame 2 and set the playMode to "play". If destine frame is different from the original one,it put to the queue the frame script of the destine frame. It unloads some children if they are not there anymore. It initialize new debut children if any,? by putting the frame 1 script of the children to the queue. It is a script,so it always happens after the initial queue. It wont disturb the initial queue structure which is setup by natural playing. Whatever frame scripts evoked by "gotoAndStop" are put at the tail of the queue. Well,I think,it is enough for such abstract explanation. I would be better to give several quiz and example to demonstrate the actions. Quizz 1: _currentframe A movie contains 4 keyframes. In frame4,put a movieclip "mc4". In keyframe 2,we make a jump by this script:
As we expect,the movie stops at frame 4. Try to answer questions below. 1. Did you see transient frame 2 shown on the screen before it jumps to frame 4 ?
2. What result do you expect about trace(_currentframe),2 or 4 ?
3. There are scripts to change the scales of mc4. What scaling do you expect the mc4 will be ?
Quizz 2: queue not stack A movie of 4 keyframes. We intend to give each frame a trace-able frameLabel. So,in keyframe 2,we add a script : frameLabel="TWO"; and in keyframe 4,we script :? frameLabel="FOUR"; Again,we jump our playhead from frame 2 to frame 4. Here is the script i of frame 2:
The _currentframe is traced out as 4,how about the "frameLabel" ? You might have expected that when the playhead moves to frame 4,the frameLabel will be set to "FOUR" by the frame 4 script,so we should get an output of "FOUR"; No ! The frameLabel is still traced out as "TWO" because the execution is still within this function block. The frame script in the destine frame 4 is not yet executed.? Any block of frame script is executed from beginning to the end without interruption. Although the movement of playhead should be accompanied by other frame script,the execution of this block is continuing without interruption. All the accompanied frame script evoked by gotoAndStop/gotoAndPlay are put in a queue and executed sequentially after this block is finished. So,the flow of script is something like below:
So,we know why the _currenframe gets traced out as 4 but the frameLabel still gets traced as "TWO".
Quiz 3 : gotoAndPlay - GOTO ? PLAY ? Now we have discussed about gotoAndStop. What about gotoAndPlay ? gotoAndPlay(2),means move playhead to frame 2 and set the playMode to "play". The result is to show frame 2 on the screen and since playMode is set to "play",the playhead will move to frame 3 after an interval. This is what "play" means. gotoAndStop(2) also moves the playhead to frame 2 but set the playMode to "stop". So,even after an interval,it stays still on frame 2. OK,here is a notorious one and also a must know quiz. A movie of two keyframes. Each keyframe has a stop() script in it. Now we put a button in another layer. This button has script:
As expected,the movie stops at frame 1. Now,what about the gotoAndPlay script in the button ? Questions: 1. The button want it to play but the frame script has a "stop()". Will it stop there or keep playing ?
2. When it stops at frame 2,will button click "gotoAndPlay" has any effect ?
In fact,the button script can be shortened as : on(release){ play();} Quiz 4: Endless loop? Becareful,this will crash your Flash. A movie of 5 frames. In the first frame,script:
What frame will it stops at ? Answer: it is an endless loop which crashes your Flash. Why ? For tutorial,I make it simpler : A movie with 2 frames. In frame 1,we script like this:
What result do you expect ? Will it play normally ?? No,it will be stuck in a looping and crash your Flash. If those script were put in a button not in frame 1,clicking of the button just makes the movie go back to frame 1 and play. Since it is a frame script,movement of the playhead shall evoke frame script. Again,the frame script moves the playhead. Then movement of the playhead evokes this script.? This results in an endless loop. The movie has no chance to finish the script queue to render the content. So,we get nothing on the screen but a crash. You can also create a similar movie to crash your Flash. In the frame 1,script "gotoAndStop(2);" and in frame 2,script "gotoAndStop(1)". The effect is similar to the example above. It loops forever before it finishes the script queue to render the content. Quiz 5: unloading and reloading. A movie of two key frames. Frame 1 contains a movieclip "mc1" and a "stop()". Frame 2 is a blank keyframe. We have a button with script:
Obviously,clicking of the button will stretch the child clip horizontally. What will happen if we move the palyhead following that command:
Nothing ! On the screen,the child movieclip seems not stretched. If fact,the child clip does get stretched. But,when we gotoAndStop(2),tha clip is unloaded. When it gotoAndStop(1),a new child movieClip is re-created. It appears as if the movie really played those two frames. So,script driving playhead movement also unload clips when the playhead moves. The same as we really play those frames sequentially. "Come on !" you might believe that it is an "of-course". Never mind,this quiz is to confirm this point. Quiz 6: Backward and reloading/duplicating? This is also a must known nortorious one. Create a movie contains 3 frames or more. Put a clip named "mc" on the stage. In the frame 1,script:
When the movie plays,we see 7 instances of "mc" on the stage. If you check debug to list objects,there are 7 movieclips. All with the same name "mc". The effect is similar to?
The usual explanation is that,if we swap the depths to the range of "programming depths - the depth greater or equal to 0",then Flash will failed to find it when the palyhead moves "backward". Consequently,Flash will recreate a new one. This result in a "duplication" of that clip. That explanation seems to make sense. But,we still don't know definitely why this happens only when the playhead moves "backward" but not "forward". You may test it by swap a clip depth to a positive number and let it play. At some frame,modify the position of the clip and make _root go back to any frame. Or let it play till the end when the _root will go back to frame 1.? You will see two instances of the clip. To avoid such conditionL
Quiz 7 : effect of combined gotoAndStop for main and child clips.? This is the most complex one and this quiz is the last example in this article. You may read it patiently. A movie with 5 keyframes. Each keyframe contains frame script with "stop()"? in frame 1. Create a symbol with 5 keyframes and each keyframes contains frame script,also with "stop()" at frame 1. Put an instance as "mc2" in frame 2 of main movie. Put an instance as "mc5" at frame 5 of main movie. Now we have a button to do our experiment:
When I click the button,here is the output:
Can you write down the queue for the on(release) block ? Here we goes:
Now we start to execute the queue.? Remember that,our playhead of main is at frame 2 now: the first mc2 and mc5 are already unloaded. Those frame script are not accessible. So,what really effective are the same as we see on the output window. Please do not make a too quick conclusion that child clip gotoAndStop only effects at the end. Lets create another similar movie but extend the existance of mc2 to frame 5,then the execution of the button will output:
Compare this output with previous queue,we pick out the difference.?
Summaries: 1. Pick gotoAndStop/gotoAndPlay correctly. In many circumstances,they are not interchangeable. 2."gotoAndStop" moves the playhead immediately. Loading and unloading processes follows. Some frame script of the child in the queue is aborted if the clip is unloaded. Unless we check the sequence of the frame script in the queue carefully,it is difficult tell what frame script is already executed before it is unload and what frame script is unload before execution. 3.If we script "gotoAndStop(4) in frame 2,it moves the playhead immediately. The stage of the scene is changed. Every thing is happening on stage of frame 4 then. After this line,anything that is referred by script is the one in frame 4. It is very confusing. 4.Because the script of destine frame is put to the queue,the remain script after "gotoAndStop" is executed before destine frame script. In other word,this remained script will be executed before initialization of all children in the destination frame. It is a bit un-natural and difficult to debug from the point of OOP. 5. It is advisable that the command "gotoAndStop" be put at the last line of frame script or button script. Anything we need to do,do it before gotoAndStop. Let gotoAndStop be the last command. Do not script anything after "gotoAndStop". (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |