AS3 How to and Tips > The AS3 Timer Class

One of the new classes introduced in ActionScript 3 is the Timer class. The class, in essence, replaces the AS2 setInterval and clearInterval functions. (Those functions are still present but deprecated in AS3.) In this How-To, we show a simple example of using the Timer class and discuss briefly performance issues related to the Timer class.

Download

Download all the well-commented source file corresponding to the applet above, eztimer.fla.

The Code in eztimer.fla

The file eztimer.fla was created in Flash CS3 with the standard frame rate of 12 fps. This is important as the performance of any instance of the Timer class is related to the swf's frame rate. In eztimer.fla, we created two input text fields, txtRepeatCount and txtMilliseconds. Using the 'Maximum characters' option in the Properties panel, we set the maximum number of characters in each of the two fields to 4. We also created two dynamic text fields, txtCount and txtElapsed. Finally, we have a button on the stage with instance name btnGo. Here is the code. (We keep comments within the code for the sake of clarity.)

 

var startTime:Number;

var timeElapsed:Number;

/*
We enable tabbing for the two input textboxes and disable it for the button. This gives us the correct keyboard interface.
*/

txtRepeatCount.tabEnabled = true;

txtMilliseconds.tabEnabled = true;

btnGo.tabEnabled = false;

/*
We restrict the characters that can be entered in the input boxes. (We also set on the stage the maximum of 4 characters for each box by entering 4 in the 'Maximum characters' field.)
*/

txtRepeatCount.restrict="0123456789";

txtMilliseconds.restrict="0123456789";

/*
We create an instance of the Timer class and store it in a variable 'tm'. The constructor requires one parameter: delay. delay is, the time interval (in milliseconds) bewteen ticks of the Timer. The second, optional, parameter stands for repeatCount; that is, the number of times you want the Timer to fire. (The default, 0, makes the Timer repeat for ever, or until the .stop() method is invoked.) We set delay to 100 initially - our Timer will "fire once every 100 milliseconds." We will be getting other values for delay from the user at runtime.
*/

var tm:Timer = new Timer(100);

/*
Each time the TimerEvent.TIMER event is dispatched, the .currentCount property of 'tm' increases by 1 automatically, and the handler, timerFires, is called. Initially, and after any call to the tm.reset() method, the value of tm.currentCount is 0.
*/

tm.addEventListener(TimerEvent.TIMER, timerFires);

/*
The timerFires function updates the contents of the dynamic textbox, txtCounter. Note that .currentCount starts with the value 0, and fires for the first time after one "tick" of the delay amount. Hence, the first value we see in this applet is 1.
*/

/*
The function also measures the time from when count began and updates txtElapsed. The time elapsed equals getTimer()-startTime. The function 'getTimer' (a method in flash.utils package) measures the time since the applet started, in milliseconds. The value for startTime was recorded when the button GO TIMER was clicked. (See the function startCounting below.)
*/

/*
Incidentally, the function getTimer has nothing to do with the Timer class. A better name for it would be: 'getTime'.
*/

/*
te.updateAfterEvent() forces a screen update after tm fires rather than wait for next scheduled screen update.
*/

function timerFires(te:TimerEvent):void {

txtCounter.text = String(tm.currentCount);

txtElapsed.text=String(getTimer()-startTime);

te.updateAfterEvent();

}

/*
When the value of the .currentCount property reaches the value of the .repeatCount property, the TIMER_COMPLETE event is dispatched. In our example, the handler function timerFinishes is called to signal the Timer object has finished. Note that if the value of .repeatCount property of tm is set to 0, then the TIMER_COMPLETE event will never fire, creating a timer that runs forever unless the .stop() method is invoked. (Indeed, after a Timer starts its currentCount will never equal 0 again, not until the Timer is reset.)
*/

tm.addEventListener(TimerEvent.TIMER_COMPLETE, timerFinishes);

/*
The background of the txtCounter textbox changes color to show precisely when the TIMER_COMPLETE event is dispatched. You will notice that it is concurrent with the final occurrence of the TIMER event.
*/

function timerFinishes(te:TimerEvent):void {

txtCounter.backgroundColor = 0xFFFFAA;

timeElapsed=getTimer()-startTime;

txtElapsed.text=String(timeElapsed);

}

/*
In our applet, pressing the btnGo button will call the startCounting function. This clears the txtCounter and txtElapsed text fields and resets txtCounter's background color to white. The function also sets the .delay and .repeatCount properties (based on the user's input), and resets the tm timer before starting it. Without calling the .reset() method, the .currentCount property would not be reset to 0 before being started.
*/

btnGo.addEventListener(MouseEvent.CLICK, startCounting);

 

function startCounting(e:MouseEvent):void {

var rc:int;

var d:Number;

txtCounter.text = "";

txtElapsed.text="";

txtCounter.backgroundColor = 0xFFFFFF;

rc=int(txtRepeatCount.text);

if(txtRepeatCount.text=="" || rc==0){

rc=10;

txtRepeatCount.text="10";

}

tm.repeatCount = rc;

d=Number(txtMilliseconds.text);

if(txtMilliseconds.text=="" || d==0 || isNaN(d)){

d=500;

txtMilliseconds.text="500";

}

tm.delay = d;

tm.reset();

startTime=getTimer();

tm.start();

}

 

Timer's Performance Issues

Setting the value for tm.delay, say, to 20 milliseconds, does not guarantee that the Timer will indeed fire every 20 milliseconds. To the 20 milliseconds, you have to add the time needed to execute the code in the handler for TimerEvent.TIMER ('timerFires' in our script), including the time needed to refresh the screen. That in turn, depends on the complexity of your visual display. The frequency with which a Timer fires is also dependent on the frame rate of your movie. It is agreed upon by AS3 experts, and it is evident from the applet on this page, that you cannot get a Timer to fire more often than approximately ten times the frame rate of your movie. Our frame rate is 12 fps so the automatic screen update happens every 83 milliseconds. Ten times more often gives every 8.3 milliseconds. Indeed, in the applet above set the count to 100 and try the values 8, 5, and 1 for the delay. The elapsed time hardly changes. The firing rate depends also on the user's system, and we find it depends also on the browser.

The question then arises: When scripting animations and timed events, is it better to use Event.ENTER_FRAME or a Timer? It depends on your application. We find that Event.ENTER_FRAME most of the time produces smoother and more predictable animations. On the other hand, for scheduling timed events, Timer is much more handy. For example, in our tutorial XML-Driven 3D Billboard - an AS3 and Flash CS4 Effect, we used a Timer to trigger changes of the billboard but we used Event.ENTER_FRAME to animate rotations of the sections.

Back to AS3 How To and Tips              Back to Flash and Math Home

We welcome your comments, suggestions, and contributions. Click the Contact Us link below and email one of us.

Adobe®, Flash®, ActionScript®, Flex® are registered trademarks of Adobe Systems Incorporated.