7 Replies Latest reply on Jul 23, 2007 8:44 AM by Newsgroup_User

    setInterval Question

    shurleynova Level 1
      I am not having the best of luck understanding the setInterval command and am a designer more than a developer so some of this ActionScript gets me confused so forgive me if the question seems kind of lame.

      How would I or can I use the setInterval to make a movie play for a certain period of time? Generally I would just create a layer that extends out as long as I want it to play the movie for and place stop(); at the end. I was hoping there was an easier or more precise way of doing this. Mainly because the fla I am creating exists on 1 frame and is all driven by action script to make clips appear at set points for a set time. I was just looking for a way to simplify the length of the whole movie action.

      I hope that made sense to someone
        • 1. Re: setInterval Question
          Level 7
          Hi shurleynova,

          setInterval runs on the system timer (loosely) and is unreliable, not
          to mention overkill for controlling animation. A simpler solution is an
          onEnterFrame loop that simply counts the number of elapsed frames and
          does stuff based on that value.

          First of all, what is the frame rate of your movie? At 30fps, for
          example, the onEnterFrame function gets called 30 times every second so
          use this in your calculations. Let's say you have a clip on the _root
          layer with the instance name "controlMe" and you want to stop it after 3
          seconds. Your onEnterFrame handler (on some other clip) would look like
          this:

          var counter=0;
          function onEnterFrame() {
          counter++;
          //90 frames/30 frames per second=3 seconds
          if (counter>=90) {
          _root.controMe.stop();
          this.onEnterFrame=undefined;
          }
          }

          This runs just once and is very rudimentary but hopefully it'll give you
          some ideas on how to proceed.

          Regards,
          Patrick


          shurleynova wrote:
          > I am not having the best of luck understanding the setInterval command and am a
          > designer more than a developer so some of this ActionScript gets me confused so
          > forgive me if the question seems kind of lame.
          >
          > How would I or can I use the setInterval to make a movie play for a certain
          > period of time? Generally I would just create a layer that extends out as long
          > as I want it to play the movie for and place stop(); at the end. I was hoping
          > there was an easier or more precise way of doing this. Mainly because the fla
          > I am creating exists on 1 frame and is all driven by action script to make
          > clips appear at set points for a set time. I was just looking for a way to
          > simplify the length of the whole movie action.
          >
          > I hope that made sense to someone
          >

          --
          http://www.baynewmedia.com
          Faster, easier, better...ActionScript development taken to new heights.
          Download the BNMAPI today. You'll wonder how you ever did without it!
          Available for ActionScript 2.0/3.0.
          • 2. Re: setInterval Question
            Rothrock Level 5
            I have to agree and disagree with what Patrick B has said here.

            Yes setInterval is not an exact interval and will vary based on many things. But then again so is the frame rate. You cannot count on 90 frame taking exactly 3 seconds either.

            The only thing that is spot on with the time is getTimer() it gives you the milliseconds since the flash file started running. But unfortunately you can only use it as an after-the-fact kind of test. So when you start you could set a startTime and then periodically test to see if enough time has passed since the startTime.

            So then the question becomes how do you check from time to time to see if enough time has gone by? The main choices are setInterval and onEnterFrame. I would suggest that it is the other way around from Patrick B's suggestion: onEnterFrame is overkill whereas setInterval is just the right amount of kill. :)

            onEnterFrame will check 30 times per second. But do you really need to stop it within 1/30 of a second? Sometimes the answer may be yes, in which case that is fine and onEnterFrame would be a good choice. However for most purposes 1/10 or even 1/4 of a second might be just fine. So in that case you can use setInterval to check at some interval that is small enough for accuracy, but big enough that the code won't have to run sooo many times. If this is something that is the only thing running then the drain on the processor really doesn't matter, but if you get lots of onEnterFrames going…

            Anyway, here is probably how I would do it:

            var myDuration:Number=3000
            var startTime:Number=getTimer();

            clearInterval(endCheckID)

            endCheckID=setInterval(endCheck,100);

            function endCheck(){
            var elapsedTime:Number=getTimer()-startTime;
            if(elapsedTime>=myDuration){
            clearInterval(endCheckID);
            myMovie.stop() \\ or whatever it is that you need
            trace("Time expired at "+elapsedTime);
            }
            }

            • 3. setInterval Question
              Greg Dove Level 4
              Hi Rothrock, I would also be inclined to use a timer over onEnterFrame as a general approach, unless there was an existing onEnterFrame requirement that I could tag it on to.

              You're using getTimer to get an accurate check, but because its using setInterval (which, along with onEnterFrame you point out as being inaccurate) it will still only get close (as you also pointed out).
              If the point is to capture the amount of time taken then getTimer makes sense... e.g. your time expired trace ... but I would be inclined to use setTimeout over setInterval for a time-based (and admittedly non-accurate!) one-off timer like this. I'd set it for 3000 millisecs and just accept that whatever elapsed time had happened was as close as it could get. That would avoid the additional executions of endCheck for all the times we know its not necessary (even at 100ms intervals).

              And I guess I say that from a theory point of view because in practice - if I'm totally honest with myself - while I do think generally ponder the most efficient way to do things... often unless I'm forced to optimise everything because what I'm doing is overheating my CPU I could very well end up just picking an approach at random.

              var startTime:Number=getTimer();
              clearTimeout(endCheckID)

              endCheckID=setTimeout(endCheck,3000);

              function endCheck(){
              var elapsedTime:Number=getTimer()-startTime;
              clearTimeout(endCheckID);
              myMovie.stop() \\ or whatever it is that you need
              trace("Time expired at "+elapsedTime);

              }
              • 4. Re: setInterval Question
                Rothrock Level 5
                Oh, I would probably use setTimeout myself, I haven't done much to test the accuracy of it so if that is important then I still don't know. My initial test seems to indicate that setTimeout is more accurate than setInterval.

                BTW, you don't need to clear the setTimeout in the function that it calls, I suppose if there is a risk that the function would get called by some other mechanism and you didn't want to have it called by the setTimeout. But that is the beauty of the setTimeout, it cancels itself when it executes.
                • 5. Re: setInterval Question
                  Greg Dove Level 4
                  @Rothrock: I didn't understand why, but after a quick search it seems like the reason why repeating timers are less accurate is explained well here (as2 & as3). They are also frame rate dependent based on my tests (setInterval is anyway).

                  Have a quick read through this.

                  http://www.bit-101.com/blog/?p=910

                  @ shurleynova - aplogies for hijacking your thread somewhat - although its still relevant its gone a bit theoretical, sorry. Please let us know if you need more help with what you're doing or if you have more questions.

                  • 6. Re: setInterval Question
                    Rothrock Level 5
                    Yes setInterval is frame rate dependent and onEnterFrame, setTimeout and, setInterval are all inaccurate, but as far as I know, getTimer() is always accurate.

                    That is why I often use a combination of setInterval and getTimer(). If the interval is small compared to the desired elapsed time, then it doesn't matter if the setInterval is off by some percentage and adds up the repeated error.

                    The final paragraph there is advocating the idea of using whatever repeating mechanism, but then using the getTimer() to know exactly how long has elapsed and to animated to the points of time.
                    • 7. Re: setInterval Question
                      Level 7
                      I have to agree and disagree with this. True, onEnterFrame isn't
                      completely reliable but it does tend to get hit closer to the real
                      framerate. An internal running at 100ms is going to be pretty imprecise
                      unless you have nothing running. Like you said, it depends on the
                      complexity of the app. But I've had timers that have fired off every 3
                      seconds and were set to 10ms. The onEnterFrame handlers were much more
                      exact in comparison. I had run these comparisons many times: when
                      writing a music sequencer (which is very touchy when it comes to
                      timing), casino games (which needed to be greatly optimized), and my
                      encryption engine which had to loop through megabytes of data to get the
                      job done. Intervals were great when the only code running was the
                      interval....that thing flew. But once more stuff was added to the stage,
                      onEnterFrame reliability stayed about the same and intervals chugged.

                      But that being said, checking for elapsed time *is* much better than
                      counting frames, that is absolutely true. I would take Rothrock's advice
                      on this one and forget my previous post. Regarding onEnterFrame/timer,
                      run the tests yourself. I can't say with 100% certainty that interval
                      won't work, just that it's not very scalable.

                      Patrick

                      Rothrock wrote:
                      > I have to agree and disagree with what Patrick B has said here.
                      >
                      > Yes setInterval is not an exact interval and will vary based on many things.
                      > But then again so is the frame rate. You cannot count on 90 frame taking
                      > exactly 3 seconds either.
                      >
                      > The only thing that is spot on with the time is getTimer() it gives you the
                      > milliseconds since the flash file started running. But unfortunately you can
                      > only use it as an after-the-fact kind of test. So when you start you could set
                      > a startTime and then periodically test to see if enough time has passed since
                      > the startTime.
                      >
                      > So then the question becomes how do you check from time to time to see if
                      > enough time has gone by? The main choices are setInterval and onEnterFrame. I
                      > would suggest that it is the other way around from Patrick B's suggestion:
                      > onEnterFrame is overkill whereas setInterval is just the right amount of kill.
                      > :)
                      >
                      > onEnterFrame will check 30 times per second. But do you really need to stop it
                      > within 1/30 of a second? Sometimes the answer may be yes, in which case that is
                      > fine and onEnterFrame would be a good choice. However for most purposes 1/10 or
                      > even 1/4 of a second might be just fine. So in that case you can use
                      > setInterval to check at some interval that is small enough for accuracy, but
                      > big enough that the code won't have to run sooo many times. If this is
                      > something that is the only thing running then the drain on the processor really
                      > doesn't matter, but if you get lots of onEnterFrames going?
                      >
                      > Anyway, here is probably how I would do it:
                      >
                      > var myDuration:Number=3000
                      > var startTime:Number=getTimer();
                      >
                      > clearInterval(endCheckID)
                      >
                      > endCheckID=setInterval(endCheck,100);
                      >
                      > function endCheck(){
                      > var elapsedTime:Number=getTimer()-startTime;
                      > if(elapsedTime>=myDuration){
                      > clearInterval(endCheckID);
                      > myMovie.stop() \\ or whatever it is that you need
                      > trace("Time expired at "+elapsedTime);
                      > }
                      > }
                      >
                      >
                      >

                      --
                      http://www.baynewmedia.com
                      Faster, easier, better...ActionScript development taken to new heights.
                      Download the BNMAPI today. You'll wonder how you ever did without it!
                      Available for ActionScript 2.0/3.0.