Introduction
Everything in Flash happens based on events. These
events can be either user initiated such as with the
onMouseDown event or the pressing of a button, or can
come as a result of the the passing of frames within the
Flash timeline. When taking advantage of the latter, one
often uses the onEnterFrame event, allowing an action or
a series of actions to occur every frame. With these
kinds of actions, animations can be coded to play
synchronous with the passing of time along the Flash
timeline. However, the progressing of the play head
along the Flash timeline though is strictly based on the
movie's set FPS (Frames Per Second) or frame rate. This
means that any action you associate with an onEnterFrame
event will be played every frame and will happen [FPS]
times a second. For example, if the frame rate of your
movie was 12 frames per second, then an onEnterFrame
event would occur 12 times every second (assuming Flash
is fast enough to keep up). SetInterval is a function in
Flash MX that allows you to set your own time-based
event similar to onEnterFrame, though based on a user
defined interval of time.
In attempt to avoid all of that onEnterFrame/play
head complexity, we can think of an interval,
conceptually, as steady drum beat from within a song.
Commonly drum beats are simple repetitions of someone
hitting a drum over and over again to maintain a
constant beat or rhythm to go along with a song. Given a
song with such a beat on a CD, if you were to insert the
CD into your CD player and hit play, you would start
hearing the song and the drum beat. Pressing stop would
then stop the song and you would no longer hear that
beat. Basically what setInterval is, is the CD player
for playing a drum beat within a flash "song" (or
movie), only you get to tell setInterval how fast you
want your drums to beat. Of course, in Flash, you wont
be beating drums, but rather executing code. Before
getting into that though, we should take a look at a
javascript function that is very similar to setInterval.
Javascript's setTimeout
For anyone accustomed to javascipt, setInterval may seem
familiar because of its similarity javascript's own
setTimeout function (note there is also a setInterval
for javascript but setTimeout helps set the stage for it
so its used here as an example). What setTimeout does is
takes a javascript operation and performs that operation
after a given amount of specified time. With this, one
would be able to, for instance, create a link which,
when clicked, would create an alert box could appear,
but only after a 2 second delay. See javascript example
below:
- <script>
- function ShowMessage(){
- alert("Click!");
- }
- </script>
- <a href="javascript: ID = setTimeout('ShowMessage()',
2000);
void(0);">Click here</a>
Output:
Click here
What this does is, when the Click here link is
pressed, calls setTimeout to run the command ShowMessage
after a time of 2 seconds (2000 milliseconds). a void(0)
is used to prevent the link from trying to load the
return value given by the setTimeout function.
SetTimeout returns a timeout identifier that allows you
to interrupt and prevent the oncoming setTimeout
operation with the clearTimeout() function. In the
instance of the above example, should you want to
prevent the alert from finally popping up, you would use
clearTimeout on the return value of the setTimeout call
(which you would have had to assign to a variable).
Example:
- <script>
- function ShowMessage(){
- alert("Click!");
- }
- </script>
- <a href="javascript: ID = setTimeout('ShowMessage()',
2000);
void(0);">Click here</a><br>
- <a href="javascript: clearTimeout(ID);">Kill
alert</a>
Output:
Click here
Kill alert
If Kill alert is clicked within 2 seconds after
clicking Click here, the setTimeout will be stopped and
ShowMessage() will not be executed.
Actionscript's setInterval
SetInterval is similar but with some important
differences. One of the biggest is that setInterval in
Flash creates a repeating operation which will
continually call a passed function over and over again -
like with a drum beat. setTimeout, as seen above, will
run the operation once, then stop. A setTimeout function
can be set to call itself over again to mimic this kind
of reoccurrence. Example:
- <script>
- function ShowMessage2(){
- alert("Click!");
- ID = setTimeout('ShowMessage2()', 2000);
- }
- </script>
- <a href="javascript: ID = setTimeout('ShowMessage2()',
2000);
void(0);">Click here</a><br>
- <a href="javascript: clearTimeout(ID);">Kill
alert</a>
Output:
Click here
Kill alert
When Click here is clicked, the alert message will
display after 2 seconds and then continue to play until
Kill alert is clicked clearing interval ID with
clearTimeout. It is important to know that because of
this, you would NOT want to call a setInterval in an
onEnterFrame event. setInterval is not meant to be
called over and over again in quick succession. It, by
itself, does that through successively calling the
function passed at the interval specified. It's
comparable to setting an onEnterFrame only not setting a
function to be called every frame, but rather once every
time the time specified has elapsed, and onEnterFrame
events aren't called in onEnterFrame events.
Another difference is that setTimeout gets passed a
string of a Javascript action which is to be evaluated
and run. SetInterval, on the other hand, gets passed a
function name (that's without the '()') which is to be
called within that interval, allowing you to specify
parameters for that function call after the interval
parameter. SetInterval also allows you to call it in two
different manners: 1) calling a direct function, and 2)
calling a method through an object. So lets look at how
setInterval is set up.
1. setInterval
( function, interval [, arg1,
arg2, ..., argn] );
2. setInterval (
object, "methodName", interval
[, arg1, arg2, ..., argn] );
The first usage takes a function and an interval with
optional arguments to be passed to that function when
its called. The first time the function is run is
interval milliseconds after this setInterval is
run, then sequential calls follow after another
interval milliseconds have gone by. A simple
example using trace() can be seen in the following:
- DisplayTrace = function(message){
- trace(message);
- }
- ID = setInterval(DisplayTrace, 2000, "Interval
called");
First, the function to be run is defined. Then
setInterval is called to run it within the given
interval, in this case, 2000 milliseconds or 2 seconds.
Because this is dealing with the first usage of
setInterval, anything after the second parameter (the
interval) are used as arguments to be passed into the
function. Here,
"Interval
called" is used as an argument for DisplayTrace,
so when DisplayTrace is called, the message argument
becomes that, which is in effect the trace received in
the output window. Passing arguments into the called
function is optional.
While that usage 1 is great for running basic
straightforward functions, however, in calling those
functions, they are run in a null scope. This doesn't
suffice for calling functions which you might want to
have run through specific objects - including methods of
those objects, which in most cases would need to be run
through that object and wouldn't function through a null
scope. That's where the second usage of setInterval
comes into play. It lets you specify the scope of the
function and where its supposed to be run.
- myObj = new Object();
- myObj.DisplayTrace = function(message){
- trace(message);
- }
- ID = setInterval(myObj, "DisplayTrace", 2000,
"Interval called");
One thing to note is how the object itself is passed
for the scope at which the function is to be run, but
the function name is passed as a string. What
setInterval does here is calls the function through the
object as through associative array referencing, i.e.
myobj["DisplayTrace"]("Interval called"); The means that
the function must be referenceable from within that
object to begin with. In other words, the DisplayTrace
function couldn't have been used if it was defined as a
normal function and not as a part of myObj itself.
Otherwise, though, this method is fairly identical to
the first usage. The function is called within the
intervals specified and all parameters after the
interval ("Interval called") are passed down to it.
In either case, setInterval returns an interval
identifier which can be used in conjunction with the
clearInterval() function to stop the interval from
continuing. ClearInterval acts similar to javascript's
clearTimeout; its just setInterval's version. When used
on an interval identifier, such as ID in the examples
above, it will prevent further occurrence of the
function call as a result of the setInterval command:
- clearInterval(ID);
An important thing to note is that with every call of
setInterval, you are not at that point also calling the
function referenced. That function isnt actually called
until the time specified has been counted fully through.
This means if you try to reference any variables that
might have been set by that function directly after
calling setInterval, you will get an incorrect value as
that function has not yet had a chance to run. If you do
want to have the function run right away, its just a
matter of calling it directly after calling setInterval.
- ID = setInterval(DisplayTrace, 2000, "Interval
called");
- DisplayTrace("Interval called");
Summary
So basically what setInterval allows you to do is make a
unique onEnterFrame type of event that occurs in the
time period you want, at the beat you want, and
not that based on the frame rate of your movie. However,
there is one very important thing to understand about
setInterval. And that is that setInterval runs
independent of frame time. This means that your interval
will occur at its set interval no matter what the speed
of the play head in Flash because setInterval is run off
of actual time periods and will not decrease in speed if
Flash starts to bog down in its own frame calculation.
With that in mind, be aware that setInterval is not
sufficient for synching with the passing of time along
the Flash timeline. In other words, if you have a movie
with a FPS of 12 frames per second and in that you have
a large movieclip moving from left to right and
repeating after 24 frames, if you created an interval to
occur every 2 seconds (approximately 24 frames) then the
call of that interval may be offset from the actual
looping of that movieclip which itself is repeating
every 2 seconds (24 frames at 12 frames per second),
because the clip may not actually loop in exactly 2
seconds but possibly slower because of Flash not being
able to draw the screen fast enough to keep up.
SetInterval on the other hand will match the interval
set exactly despite how fast flash is able to keep up
with drawing the frames on the screen. Then again, if
Flash cant keep up with the actual setInterval calls, it
wont do that either.
Along the same lines its good to know that
setInterval is also not as reliable as you might think.
Actual timing and the timing you set won't match up as
well as you might like. For example, the actual timing
of the interval can be influenced by the set frame rate
of the movie. Here are some examples of approximate
actual timing for an interval set at 100 milliseconds at
different frame rates (thanks to Roger for the
information):
1 fps: |
interval = 127 ms |
2 fps: |
interval = 125 ms |
5 fps: |
interval = 105 ms |
10 fps: |
interval = 102 ms |
11 fps: |
interval = 183 ms |
12 fps: |
interval = 175 ms |
15 fps: |
interval = 134 ms |
You can see here that 100 milliseconds can be far off
from 100 milliseconds to setInterval. Be cautious of
this and don't be setting your watches to any Flash
setIntervals.