How to Pause a Timeline (AS3)
If the title of this blog entry sounds familiar, it may be because you saw the ActionScript 2.0 equivalent on this site over a year ago. In the comments to that article, a reader named Eric asked how to pause a timeline in ActionScript 3.0 (very different from AS2, as it turns out). There’s a significant benefit to using ActionScript (whatever version) to temporarily halt the timeline, then resume after a few seconds: it’s all about saving yourself the hassle of horizontal scrolling. Consider pausing for five whole minutes. At the default 12fps, that would require 3,600 frames of timeline real estate. With code, you can pull it off in a single frame. Let’s take a look.
An answer short and sweet
Create a script layer, if you haven’t already. (It’s not strictly a requirement to put ActionScript into a layer named “scripts,” “actions,” or the like, but it sure makes locating your code much quicker in cases where the FLA has dozens of layers.) Wherever you’d like the timeline to pause, add a keyframe to your script layer and type the following (remember, this is ActionScript 3.0) …
stop();
var timer:Timer = new Timer(2000, 1);
timer.addEventListener(
TimerEvent.TIMER,
function(evt:TimerEvent):void {
play();
}
);
timer.start();
How it works
The first line, stop(), simply stops the timeline. If you’d like, you may use the this property as a reference to the timeline you’re in — e.g. this.stop(); — but the reference is assumed in this context, and the reference points to the MovieClip instance in which the code appears (timelines are movie clips). In AS2, there was a global function stop() that was essentially the same thing as the MovieClip.stop() method, and you distinguished between the two by preceding stop() with a movie clip reference or not (myClip.stop(), this.stop(), etc.). In AS3, the function simply doesn’t exist, so you’re always using the MovieClip method.
Next, an arbitrarily named variable, timer, is declared and set to an instance of AS3’s new Timer class (because ActionScript is case sensitive since Flash Player 7, the instance name timer and the class name Timer are considered two different terms). Timer allows you to delay or repeatedly trigger a function of your choosing at a specified time interval. Two parameters are fed into the constructor: a) 2000, which means two thousand milliseconds (2 seconds), and b) 1, which tells the Timer instance how often to trigger the desired function. This is a change in the way setInterval() works in AS2. The setInterval() function triggers its assigned function repeatedly until asked to stop. A do-it-once scenario means you’ve either got to use clearInterval() to stop the triggered function after one go, or use the setTimeout() function instead of setInterval(). The Timer class combines the best of both worlds: specify 1 to trigger something once, 0 to trigger something forever (until told to stop), and any other number to trigger a function that many times.
Next, an event handler assigns a function to the timer variable in the manner of practically all event handling in AS3: obj.addEventListener(event, function). In this case, the event to listen for is TimerEvent.TIMER, and the function is a function literal in the following form:
function(evt:TimerEvent):void {
play();
}
… which neatly starts the timeline again.
Finally the Timer instance, timer, must be kicked into gear: timer.start().
If you want to pause for three seconds, substitute 2000 with 3000. Six and a half seconds would be 6500; and so on.
A note about variables in ActionScript 3.0
In the AS2 version of this code, a variable named interval is declared via the var keyword, much like timer is declared here. In AS2, you may copy/paste that version into as many keyframes as you like. Each new time the playhead sees var, it simply creates a new variable by whatever name was specified (e.g. interval), and the existing instance of that variable is overwritten. In AS3, things are different. Variables may only be declared once per timeline (once per object), so if you want to pause your timeline at more than one keyframe, you’ll have to leave off the var declaration in all cases after the first one:
// First keyframe used …
stop();
var timer:Timer = new Timer(2000, 1);
timer.addEventListener(
TimerEvent.TIMER,
function(evt:TimerEvent):void {
play();
}
);
timer.start();
// Any keyframe after the first time used …
stop();
timer = new Timer(2000, 1);
timer.addEventListener(
TimerEvent.TIMER,
function(evt:TimerEvent):void {
play();
}
);
timer.start();
September 15th, 2007 at 4:10 pm
Posted this in the other article:
setTimeout(); works for me in AS3, but not setInterval();
stop();
setTimeout(function () { play();}, 2000)
If you’re just going for a simple two-second pause on the timeline.
September 27th, 2007 at 10:14 am
io,
Ah, I saw your similar comment in the AS2 version of this article. For convenience, I’ll post the same reply here, as it applies in this case, too:
Although the
setTimeout()andsetInterval()functions are still available in ActionScript 3.0, they’ve been re-routed to theflash.utilspackage; in addition, the ActionScript 3.0 Language Reference strongly recommends theTimerclass instead: “Although you can use this method, it will generate a compiler warning. Instead of using thesetInterval()method, consider creating aTimerobject, with the specified interval, using 0 as therepeatCountparameter (which sets the timer to repeat indefinitely).” sourceNovember 12th, 2007 at 5:51 pm
David I just bookmarked your blog. This article was professionally executed and was extremely easy to follow, a rarity these days. I am going to use this script on a current project www.warriorepic.com. Check it out if you would like, the site has only been live for a few days and I have yet to implement any flash on it.
Peace
Brice
November 14th, 2007 at 8:36 pm
Brice,
Thanks!
November 18th, 2007 at 7:15 pm
Thanks David,
This code works a treat in Flex…..
Just replace the play(); function with the function you want to call..
November 19th, 2007 at 12:10 am
Chris,
You bet.
The Flex framework is written in ActionScript 3.0, so standard AS3 classes, such as
Timerare usable in both worlds.November 29th, 2007 at 2:55 pm
I may be a little off topic, but I’ve been searching for a way of doing this without any luck and would like to see if anyone else has encountered the same — In AS2 I would use setInterval and pass in a reference to the needed movieclip so that it can be found when the interval is complete. Using AS3 with the Timer object I haven’t found a way of referencing the needed movieclip once the timer event has been called. Anyone know a good way of doing this?
November 29th, 2007 at 3:24 pm
Jeff,
The reference needed in AS2 was a (potentially) frustrating result of the way scoping works in that version of of the language. In AS3, your
Timerevent handler can reference the desired movie clip in the same way it would if that code were simply sitting on the timeline (rather than inside an event handler). Much easier!December 4th, 2007 at 1:27 pm
let me preface this with, “I’m not much of a coder”, I’ve tried implimenting the code but get the following errors
The class or interface ‘Timer’ could not be loaded.
December 4th, 2007 at 1:35 pm
martoon,
It sounds like your document is configured for ActionScript 2.0, and the approach shown above is for ActionScript 3.0. If you’re using Flash CS3, you can go to File > Publish Settings > Flash tab and choose 3.0. If you’re in an earlier version of Flash, use the 2.0 approach.
December 4th, 2007 at 2:03 pm
Great, that solved it. Thanks!
December 10th, 2007 at 10:59 am
By using the packages and using your favorite text editor do you need to put anything on the stage in flash, when using AS 3.0?
just a question
[Note: This comment seems to refer to another topic, as the article about pausing the timeline doesn’t need classes or packages.]
December 10th, 2007 at 1:44 pm
Gary,
If you use Flash CS3’s Document class field in the Property inspector, you can associate your FLA with any AS3 class definition you like, as long as that class extends either
SpriteorMovieClip, as appropriate. You could, in fact, put absolutely nothing on the Stage.December 12th, 2007 at 4:00 pm
I typed it using notepad then copied over to flash to see if there were any errors and these are the ones i found
I have another 2 errors that i cant seem to find a solution for on the web.
error 1 is 1084: syntax error: expecting rightparen before colon.
here is the code
_stage.addEventListener(MouseEvent:MOUSE_MOVE, draw);
error 2 is 1013: theprivate attribute may be used on on class property definations
here is the code
private function dispatchColorPicked (mouseEvent:MouseEvent):void
December 14th, 2007 at 10:42 am
Gary,
I just realized we’ve been jumping around a bit on these blog comments. No harm done, but this particular entry (pausing the timeline) doesn’t make use of classes or packages, so I’m mentioning that in case the topic confuses other readers.
Your first error may be due to your
_stagereference (not sure). By the looks of it, your parentheses are certainly in the right place. Unfortunately, these messages sometimes get confused about what line is the cause of an error. Your summary of error 1013 seems to have a few typos, so I’m not sure what’s going on. It certainly is possible to useprivateon a class member, such as a method or property, but only if that member is used inside the class only.December 14th, 2007 at 11:29 am
I am creating a animation nested inside a movie clip and I have two buttons on the stage.
button one is the pause button
I would like to pause the movie clip or everything on the stage when this button is pressed.
button two is the play button
I want everything to resume playing when this button is pressed.
I know how to do this in AS2 but not in AS3. I have the basic button code but I can’t get pause():void or resume():void to work. Do you have any suggestions?
December 14th, 2007 at 11:39 am
Shelly,
The timelines of movie clips run independently from the timelines in which those movie clips reside. If you stop the main timeline, for example, a movie clip inside that timeline will continue to play — and it sounds like you already understand that part.
To pause both the main timeline and a given movie clip symbol, you’ll have to invoke
MovieClip.stop()on both those entities. The movie clip will need an instance name, of course, and it sounds like you don’t need aTimerinstance in this case. So it might go something like this:December 17th, 2007 at 10:16 am
Thank you! perfect! You’re so awesome! Here is what I made just testing the script and playing around trying to learn AS3. I know its nothing special but it works and thats all that matters!
December 17th, 2007 at 4:27 pm
Shelly,
Fantastic! Glad to hear it.
January 10th, 2008 at 5:38 am
i read your tutorial and found it is quite useful, i hope it works fine on my project.
regards,
January 14th, 2008 at 4:49 pm
Hunka,
Thanks!
February 15th, 2008 at 12:46 pm
David,
Using AS3. I had no problem creating an instance of the timer class - it works fine. My problem is this - how do I get the timer to start upon the occurrence of a MOUSE_UP event??
MOUSE_UP event now gets a new URL for my button instance, but I want to delay the GetURL function for 2000ms to play the remaining animation that’s already playing as a result of MOUSE_DOWN.
Steve
February 16th, 2008 at 6:36 pm
Steve,
Assuming a button with the instance name
myButton, you could do this:This example is very close to what’s shown in the original article, only the
start()method is called inside theMOUSE_UPhandler. (Note that the AS3 version ofgetURL()isnavigateToURL(), which requires an instance of theURLRequestclass, rather than just a string).March 9th, 2008 at 6:44 pm
Hey I was hoping someone could help me out. I’m trying to build a custom flv player with a scrub bar, in action3.0, I’ve been using Lee’s tuts to build in 2.j0 and converting to 3.0 the only thing I can’t figure out is the scrubber part. Is there a tut out there done in 3.0
Thanks
J.
March 10th, 2008 at 1:00 pm
Jeremiah,
This particular blog entry is about pausing movie clip timelines, but I do have a related tutorial on this blog for an AS2 scrubber for FLVs. I do plan to update it to AS3 sooner or later, but for the time being, at least, it may give you ideas on how to proceed in your conversion.
How to Build a Flash Video (FLV) Progress Bar (Part 2)
April 21st, 2008 at 10:18 pm
Thank you David for that commented example, having not done any flash for nearly ten years you have almost saved my life.
April 25th, 2008 at 3:10 pm
Sensi,
Glad to help!
May 21st, 2008 at 11:45 am
Thanks David! This tutorial was exactly what I was looking for. This was much easier to understand for me than the olds AS2 way of doing things.
Thanks Again,
Rick
June 3rd, 2008 at 8:20 am
Just wanted to say THANK YOU! I’ve just spent hours trawling through information about the timer class but nothing was using it in the way I wanted and then I came across this page. PERFECT
June 3rd, 2008 at 12:49 pm
To Rick …
Glad to hear it!
To James …
You’re welcome.
August 6th, 2008 at 3:50 am
finally i’ve fond someone who explains all this code without me wanting to headbutt the screen in frustration. many thanks david !
now fr my stupid question ….
the ‘1′ which tells the timer how many times to pause….i tried this but my flash movie keeps pausing it forever, ie each time the timer comes to the frame.
am i doing something wrong or just being thick ?
August 9th, 2008 at 10:33 pm
brian,
Aha! I see what you’re thinking (I think!). Nah, you’re not being thick … you’re just interpreting the concept of “trigger this function once” in a different way.
When the playhead enters the frame in which this code appears — and this is true of any and every time the playhead enters this frame — Flash obeys the instructions and performs
timer.start();, which means the event handler associated with thetimerinstance is going to do its thing … once.If you were to replace that 1 with a 2, the
TimerEvent.TIMERhandler would perform its duties twice (following two 2-second delays). If 3, then thrice (following three 2-second delays). 0 repeats forever.Does that nail it?
November 23rd, 2008 at 9:55 pm
May I ask — I’m experimenting for the first time with AS3.
I thought I would be able to use the script four different times on a single timeline but, when I do, I get the error message “A conflict exists with definition timer in namespace internal.”
What should I do to reset the variable “timer” in each instance? I learned that I can change the variable name from “timer” to “timer2″, “timer3″ and “timer4″ and the movie will play correctly. But I’d like to use only “timer”, if possible.
I also learned about “removeEventListener” and tried to use it but so far have not been successful with it.
Thank your for your time.
November 26th, 2008 at 9:15 pm
Chris,
This is covered in the note at the end, actually. In AS3, the Flash compiler doesn’t let you re-declare variables in the same scope, so all you have to do is drop the declaration keyword (drop the
var) in subsequent keyframes.So, in the first keyframe this appers:
var timer:Timer = new Timer( ... )And any time after that:
timer = new Timer( ... )January 16th, 2009 at 7:25 pm
This is the only script that I found (AS3) that actually works. So many other scripts just blow up. I was not having luck with dropping the declaration ‘var’ of subsequent frames - so I use the timer1, timer2 solution from Chris - thanks to both.
January 28th, 2009 at 5:20 pm
David,
Thanks for your help. Much appreciated. I do see what you mean about it being covered in the note at the end. Missed that when I first read the instructions I think because I found AS3 kind of overwhelming. Much to absorb.
Thanks again, Chris
February 9th, 2009 at 6:26 am
Hi David,
Your articles really help me a lot, but I’m still in trouble with this stop-other-movieclips thing.
It’s a little bit similar with Shelly Colvin question, except that this time I have a bigger presentation with a dozen of nested movieclips.
I didn’t want to write every instance name inside de pauseTimelines function, instead, I wanted to create a loop to get all the movieclips on the root and stop them.
I know how to do this in AS2, but I had no luck converting it to AS3.
(Sorry for my english, I’m brazillian and don’t write that often).
February 11th, 2009 at 6:16 pm
My question is simple. I haven’t used flash in a while.. the last version I used you could use the actionscript menu to enter a stop command to stop the movie. I know in CS4 I can type the stop command, but the question is where did they move it to in the menu. I think it was version 8 that had basic command right at the top in the actions window. Don’t see those basic “control” commands.. so where did they move them to. How do you enter these simple command without typing them. Stop, play etc. Just can’t find them in the menu structure.
Thanks
February 12th, 2009 at 8:19 pm
To Jerry …
Glad to hear this approach works for you! I wonder you accidentally mistyped something in the case of those other approaches? I’d be curious to see what they were. Flash usually gives you half a dozen ways to solve any given problem, which is sometimes a blessing and sometimes a curse.
To Chris …
Keep your chin up! It was overwhelming to me at first too, but so was AS2. With practice, it starts to gel — and for me, AS3 ended up making more sense, all told, than AS2.
To Daniel …
Cool. It’s not too hard, as long as you’re doing in the confines of a particular scope, such as the main timeline.
The principle is the same, actually, but you go about it a different way. In AS2, you can use a
for..inloop, test to see if the current object is a movie clip, then invoke theMovieClip.stop()method on it, like this:That will stop all movie clips in the scope of the
for..inloop, no matter what their instance names are (or even if they don’t have instance names).In AS3, those movie clips belong to a display list, which means you can access them directly by instance name if you know it. If you don’t know it, or don’t care to know, you can simply loop through the display list of the current scope and pull off the same trick. Instead of a
for..inloop, just use aforloop, like this:Here, the
typeofoperator is replaced byis, which compares against an actual class name (MovieClip) rather than a string representative. If the condition is true (it’s a movie clip), cast the expressionthis.getChildAt()as aMovieClip— otherwise Flash thinks it’s aDisplayObject(which it is, but it’s also aMovieClip; andDisplayObjects don’t have astop()method — and stop the clip.March 3rd, 2009 at 3:00 pm
Hi David, I am trying to make a Pedestrian crosswalk for a road. So when the pedestrain presses the button, 2 seconds after the car(which is a movie clip) will stop at the a specific frame, or specific place right behind the crosswalk or intersection. The car will only stop right behind the crosswalk and if its already in the crosswalk or after it, it will continue moving.
Thanks david
June 21st, 2009 at 2:26 am
I am trying to use the timer class discussed here and cannot get a firm understanding. Here is what I am trying to do:
I made a marquee, similar to the html marquee, the text is a long string broken up into segments. I have a tween to move the marquee from beginning to end and an array containing stop points at which I want the marquee to pause, wait, and then continue. I want to set the interval for the pause and learned that I need to use a timer which is fine. I understand how to set up the timer and send it to a function… it is inside the function that I get confused… I simply want the tween to stop and wait for a specified length of time and then continue on but I am unable to figure out how to tell AS3 to do nothing. I thought I had it once and had the timer all set but as soon as I entered the second leg of the journey (movieclip_mc.continueTo(x, d)), the pause no longer functioned. It was as if ActionScript ignored the pause function totally and I am not understanding how this is possible and how to prevent it. I have been searching for this for several days now beating my head against the wall at every step. Any assistance would be appreciated.
June 23rd, 2009 at 5:49 am
I’m new to ActionScript 3 and must also congratulate you on a clear, concise and easily readable and understandable tutorial here. Going back to your original article on pausing the timeline - I can achieve this without problem and I can also put the same ‘amdended’ code in subsequent keframes to pause the timeline. I’m struggling though to create a class for this function so that I can call it in a number of keyframes in a number of different MC’s all pertaining to a single project. In other words (and excuse my lack of correct terminology here) I want to create a single .AS file containg a “Pause The Timeline” function that I can call from various .fla’s in a format like:
timelinePause(2000);
where 2000 is the number of milliseconds to wait before continuing to play the timeline. Is this possible? Is there sample AS3 code available? Any help or a pointer in the right direction would be greatly appreciated. Thanks.
June 23rd, 2009 at 9:51 am
To Shaughn …
You wrote back in March, so I apologize for the delayed reply, here. I realize you may have already moved on. Your description indicates at least one “if” scenario, which means the pause script won’t be enough, on its own, to handle what you’re after. I could see using an
ifstatement to check the vertical position of the pedestrian movie clip (assuming it’s a movie clip), but that would only work of the coordinates of the pedestrian clip change over time. If your pedestrian’s movement happens inside this pedestrian clip — which it would if you’re using timeline animation (that is, a tween) in that clip — then you’d have to use some other means of indicating whether or not the pedestrian is present (or where it is present).Whatever your means, you could add an
ifstatement just before the operative line of code (theplay()method):In the above revision, the timeline in which this code appears would only continue playing if a movie clip with the instance name
pedestrianCliphappens to be positioned lower than 100 pixels from its parent’s registration point.To Wayne …
There are other approaches (e.g., an
enterFrameloop that checks against an incrementing number), but a timer is probably the least hassle.The trick isn’t so much to instruct AS3 to do nothing, but rather, to hold off, for the desired length of time, on instructing it to do anything. You mention a
continueTo()method, but that isn’t part of theMovieClipclass, so I’m assuming you’ve got some other code in play here (maybe one of the numerous popular tweening APIs?). If you’re tweening your movie clips with code, then the pause script I’ve suggested may not do anything. At rock bottom, it simply stops the current timeline (thus pausing any tweens, by happenstance, in that timeline), waits, then plays that timeline again.It may help you sort out the code a bit if you see the same thing presented with a named function, rather than a function declaration inside the
addEventListener()method. Check it out:All the mechanics are the same … it’s just that the functional part, the part that restarts the timeline, is now declared as a named function, and the name of the function is now used as the second parameter in the
addEventListener()method. In this arrangement, the code looks a bit less cluttered. I don’t know if that helps you get a better grasp on theTimerclass, but I hope so! Be aware that you can put whatever you like inside the to-be-triggered function (here namedresume). In this case, there’s only a single line of code (play()), but you could add a second line after that (say, atrace()statement, so you can send messages to the Output panel, which helps with troubleshooting), or as many additional lines as you like.If the pausing doesn’t do what you expect during the second leg of the journey, it may be that you forgot to re-invoke the
time.start()line? In the constructor (new Timer(2000, 1)) the second parameter determines that the timer only fires once. If you want it to fire more often, change that 1 to a 0 (repeats forever), 2 (repeats twice), and so on. In this particular case, for pausing a timeline, a value of 1 likely makes the most sense, because after thestop()method, you only want to resume the timeline once. When you want to pause the timeline again later, you have to again provide astop()method (in some other frame, down the line), and then again start the timer (time.start()).To Mike W …
You bet! In fact, I included a scenario just like this in ActionScript 3.0 Quick Reference Guide (O’Reilly). If you visit the book’s page on the O’Reilly site …
http://oreilly.com/catalog/9780596517359/
… you’ll see an Examples link beneath the image of the book cover. Use that to download AS3QRG_samples.zip (approx 53MB), and you’ll find a working example in the Chapter 6 ZIP file. (Look for the CompanyTemplate example.)
June 24th, 2009 at 12:04 am
Good Morning David - thanks for the prompt and perfect assistance. Its exactly what I need and I can see where my attempts were coming short. I will be investing in your collaborative publication - if its anything like your online tuts, its sure to be most helpful. Thanks again. Mike
June 24th, 2009 at 8:16 am
Mike W,
Glad to hear that! The O’Reilly book is a compare/contrast reference to help developers migrate from ActionScript 2.0 to 3.0. You can find a number of excerpts on the Adobe site at this URL:
http://www.adobe.com/devnet/actionscript/articles/as3_quick_ref.html