Your geeky programming portal

Tutorial: How to Pause a Timer

Content on this page requires a newer version of Adobe Flash Player.

Get Adobe Flash player

Content on this page requires a newer version of Adobe Flash Player.

Get Adobe Flash player

How to pause in ActionScript 3.0

The integrated Timer class in ActionScript 3.0 has a major downside - it can't pause. So what can we do to solve this problem?
The Timer class has two functions that we usually use:

.stop() : stops the Timer and resets the delay.

.start() : begins the Timer. It will set the delay to the value passed into new Timer(delay:Number,repeat:Number).

If, let's say, a timer with a delay of 1000 milliseconds is created. We stop it when it has executed 500 milliseconds. Now, we still have 500 milliseconds left, but if we start it again it will restart with a delay of 1000. If we repeatedly stopped it half-way and started it again it would never finish.

Explanation to the movies above:
Both movies have a box moving from left to right and vice versa. Every 1,1 second the boxes change colors.

(NOTE: Keep in mind that the timer is exact and the flash player isn't. This can result in some inaccuracy)

The first movie ("Bad Timer") uses the integrated Timer class. When you hit PAUSE it throws the .stop() function and when you hit RESUME it throws the .start() function.
The point is to show that if you pause/resume repeatedly the box won't change color as it should.

The second movie ("Good Timer") uses a homemade class that I will show you how to make in a moment. The class stores the time that the timer has runned when paused and substract it from the original delay when started.


The PerfectTimer Class
I am a very humble person so I have called the class "PerfectTimer". Let's begin by taking a look at the whole class and then I will explain the idea behind and how you can use it in your own projects.

Code Snippet

  1. package {
  2.  
  3. import flash.utils.Timer;
  4. import flash.utils.getTimer;
  5.  
  6. public class PerfectTimer {
  7.  
  8. public var _delay:Number;
  9. public var _lastTime:Number;
  10. public var _repeat:Number;
  11. public var _thisTime:Number = 0;
  12. public var timer:Timer;
  13.  
  14. public function PerfectTimer(delay:Number, repeat:uint=0):void {
  15. _delay = delay;
  16. _repeat = repeat;
  17.  
  18. timer = new Timer(delay,repeat);
  19. }
  20.  
  21. public function start():void {
  22. _lastTime = getTimer();
  23. timer.start();
  24. }
  25.  
  26. public function pause():void {
  27. timer.stop();
  28. _thisTime = getTimer() - _lastTime;
  29. }
  30.  
  31. public function repeat(new_delay:Number):void {
  32. _lastTime = getTimer();
  33. timer.delay = new_delay;
  34. }
  35.  
  36. public function resume():void {
  37. if (_thisTime > timer.delay) {
  38. _thisTime = timer.delay;
  39. }
  40. timer.delay -= _thisTime;
  41. _lastTime = getTimer();
  42. timer.start();
  43.  
  44. _thisTime = 0;
  45. }
  46. }
  47. }

As you might have noticed is the class created as a normal Timer with 2 parameters - delay and repeat, where the repeat is optional.

line 21-24 "start()" : We store the current time in the variable "_lastTime".

line 26-29 "pause()" : The variable, "_thisTime", calculates the time difference from when the timer was started till it was paused.

line 31-34 "repeat()" : This is the tiny downside of this class. If the timer repeats more than once we will have to reset the "_lastTime". You will also have to pass in the delay once again. This can be used in our favor - if we want to change the delay everytime the timer repeats (maybe a random delay).

line 36-45 "resume()" : This is it. Now, we will use all of our stored values to calculate the already spent time and substract it from the timer.delay and then reset all the parameters (_lastTime and _thisTime). The timer will now start with the remaining delay.

The big difference is that the class creates a Timer within itself. This means that you will have to go down a layer if you will assign any event to the timer. Let's say we work in another external AS3 script and we wan't to create and work with our new and powerful Timer class. (remember to store the scripts in the same folder).

Code Snippet

  1. var timer:PerfectTimer = new PerfectTimer(1000);
  2. /* remember NOT to assign the listener directly to the PerfectTimer!
  3. instead assign it to the timer inside the PerfectTimer :) */
  4. timer.timer.addEventListener(TimerEvent.TIMER, executeAndRepeat);
  5. timer.start();
  6.  
  7. pause_btn.addEventListener(MouseEvent.CLICK, pauseGame);
  8. resume_btn.addEventListener(MouseEvent.CLICK, resumeGame);
  9.  
  10. function executeAndRepeat(event:TimerEvent):void {
  11. // do your magic
  12.  
  13. timer.repeat(1000);
  14. }
  15.  
  16. function pauseGame(event:MouseEvent):void {
  17. // pause all events
  18. // ex. removeEventListener(Event.ENTER_FRAME, handleEverything);
  19.  
  20. timer.pause();
  21. }
  22.  
  23. function pauseGame(event:MouseEvent):void {
  24. // resume all events
  25. // ex. addEventListener(Event.ENTER_FRAME, handleEverything);
  26.  
  27. timer.resume();
  28. }

NOTE: Notice in line 4 that we dig down a level and assign the event listener to the timer inside the PerfectTimer class. If you want to use any integrated Timer function you will have to do the same.

By Lewinzki


Lewinzki.com and all of its content is created by Thomas Jensen alias Lewinzki. Email: webmaster@lewinzki.com

00:00:00