[AS3] Precise Timer approach #1

by Bernd on September 24th, 2009

If you need to implement a ordinary countdown in your Flex/AIR or plain Flash application there is no way around the Flash built in Timer (flash.utils.Timer, since 9.0). Unfortunately this Timer isn’t accurate, not even close. Even worse, the longer it runs, the more it will be off time. Traced out the first 20 seconds of a simple Timer which fires every 1000ms, we are 1800ms off!

1001
2110
3262
4340
5583
6678
7757
8836
9908
10986
12081
13149
14235
15312
16383
17460
18543
19633
20712
21837

So I did some tests with setInterval, a hangover function from AS2, which lead me to the same result. Since I needed a timer that runs accurate my idea was to calculate the gap on every cycle and adjust the internal timer. Use it just like the normal Timer.

package
{

import flash.events.EventDispatcher;
import flash.events.TimerEvent;
import flash.utils.Timer;
import flash.utils.getTimer;


public class PreciseTimer extends EventDispatcher
{

private const INSPECT_TIME:int = 100;


private var _timer:Timer;
private var _startTime:int = 0;


private var _delay:int = 0;
private var _repeatCount:int = 0;
private var _continueForever:Boolean;


public function PreciseTimer(delay:int, repeatCount:int)
{

_delay = delay;
_repeatCount = repeatCount;
_continueForever = repeatCount <= 0;
init();

}


private function init():void
{

_timer = new Timer(INSPECT_TIME, 0);
_timer.addEventListener(TimerEvent.TIMER, onTimer);

}


public function start():void
{

_startTime = getTimer();
_timer.start();

}


public function stop():void
{

_timer.stop();

}


private function onTimer(event:TimerEvent):void
{

var timer:int = getTimer();
var durations:int = timer – _startTime;


if (durations > _delay)
{

if (_continueForever)
{

dispatchEvent(new TimerEvent(TimerEvent.TIMER));

}
else if (_repeatCount -- == 1)
{

stop();
dispatchEvent(new TimerEvent(TimerEvent.TIMER));
dispatchEvent(new TimerEvent(TimerEvent.TIMER_COMPLETE));

}
else
{

dispatchEvent(new TimerEvent(TimerEvent.TIMER));

}


_startTime = timer – ((durations – _delay))

}

}

}

}

So far, so good, here are the figures. For my purposes, this is close enough!

1093
2044
3069
4003
5025
6077
7044
8054
9002
10070
11116
12022
13040
14084
15003
16046
17049
18094
19020
20056
Posted in category: AS3
Tags: , , , ,
5 Comments
  1. Hello from Russia!
    Can I quote a post in your blog with the link to you?

  2. Great stuff, quick fixed my problem and helped me a lot!!!!!

  3. errata

    replace:
    else if (_repeatCount — == 1)
    with:
    else if (_repeatCount — == 1)

    • thx!

      actually it was “_repeatCount --” (minus minus), wordpress formated it wrong

Leave a Reply

Note: XHTML is allowed. Your email address will never be published.

Subscribe to this comment feed via RSS