Recipe 1.12.
Repeating a Task over Time
Problem
You want to perform some action or actions over
time.
Solution
Use the Timer class. Alternatively, listen
for the enterFrame
event of a sprite.
Discussion
The Timer class is new to ActionScript
3.0, and is recommended over the earlier setInterval( ) and setTimeout( ) functions. When you
create an instance of the Timer class, it fires timer
events at regular intervals. You can specify the delay between
events and how many times you want the events to fire in the
Timer constructor:
var timer:Timer = new Timer(delay, repeatCount);
You use addEventListener to set up a
method to handle these events. After you create the timer and set
up a listener, use its
start( ) method to
start it and stop( ) to stop it.
The Timer class is part of the
flash.utils package, and there is also a TimerEvent
class in the flash.events package, so those need to be
imported:
package {
import flash.display.Sprite;
import flash.events.TimerEvent;
import flash.utils.Timer;
public class ExampleApplication extends Sprite {
// Declare and initialize a variable to store the value
// of the previous timer reading.
private var _PreviousTime:Number = 0;
public function ExampleApplication( ) {
var tTimer:Timer = new Timer(500, 10);
tTimer.addEventListener(TimerEvent.TIMER, onTimer);
tTimer.start( );
}
private function onTimer(event:TimerEvent):void {
// Output the difference between the current timer value and
// its value from the last time the function was called.
trace(flash.utils.getTimer( ) - _PreviousTime);
_PreviousTime = flash.utils.getTimer( );
}
}
}
The
getTimer( ) function (previously a top-level function), has
been moved to the flash.utils package as well. This
simply returns the number of milliseconds since the application
started.
In the preceding example, even though the
interval is theoretically 500 milliseconds in practice its accuracy
and granularity depend on computer playback performance in relation
to other tasks demanded of the processor. There are two
implications to this:
If you want to emulate the functionality of the
setInterval( ) function, set the repeat count to zero. This
causes the timer event to fire indefinitely. In this case, the
stop( ) method is analogous to the clearInterval( )
function, and stops the timer from firing further events.
Similarly, if you want to duplicate the
setTimeout( ) function, set the repeat count to one. The
timer waits the specified amount of time, fires one event, and
ends.
One of the neat things you can do with the
Timer class is create animations that are independent of the
movie's frame rate. With a timer you can call a method at any
interval you want. Here is an example in which two timers are
setone for a square sprite (every 50 milliseconds)and one for a
circle sprite (every 100 milliseconds):
package {
import flash.display.Sprite;
import flash.events.TimerEvent;
import flash.utils.Timer;
public class ExampleApplication extends Sprite {
private var _square:Sprite;
private var _circle:Sprite;
public function ExampleApplication( ) {
// Create the two sprites and draw their shapes
_square = new Sprite( );
_square.graphics.beginFill(0xff0000);
_square.graphics.drawRect(0, 0, 100, 100);
_square.graphics.endFill( );
addChild(_square);
_square.x = 100;
_square.y = 50;
_circle = new Sprite( );
_circle.graphics.beginFill(0x0000ff);
_circle.graphics.drawCircle(50, 50, 50);
_circle.graphics.endFill( );
addChild(_circle);
_circle.x = 100;
_circle.y = 200;
// Create the two timers and start them
var squareTimer:Timer = new Timer(50, 0);
squareTimer.addEventListener(TimerEvent.TIMER, onSquareTimer);
squareTimer.start( );
var circleTimer:Timer = new Timer(100, 0);
circleTimer.addEventListener(TimerEvent.TIMER, onCircleTimer);
circleTimer.start( );
}
// Define the two handler methods
private function onSquareTimer(event:TimerEvent):void {
_square.x++;
}
private function onCircleTimer(event:TimerEvent):void {
_circle.x++;
}
}
}
It is also possible to use the enterFrame
event of a sprite to have some action (or actions) repeat over
time. The Timer technique offers some advantages over the
enterFrame event method, most notably that it allows you to
create intervals that differ from the frame rate of the
.swf. With enterFrame, the handling method is called
at the frame rate.
With that said, there are still times when using
enterFrame is appropriate. For example, you may want
something to occur at the frame rate of the .swf. One such
scenario is when you want to reverse the playback of the frames in
a movie clip.
|