Pausing a Flash game or movie when there is a Timer event

Not so long ago I showed you how to pause a Flash game or movie detecting its focus using ACTIVATE and DEACTIVATE events.

Unfortunately a new problem comes when you have Timer events.

Although you may think you just need to stop and restart the timer, the internal counter resets when you start it again.

So let’s say you have a timer event you have to trigger at every second, if you pause the game, and then unpause and pause it again in less than a second, the timer will never be triggered.

The solution is to keep track of how much time passed since the last tick and the pause, and when the user unpauses the movie, setting the delay of the first timer to be triggered to the difference between the normal delay and the difference between the normal delay itself and the time passed since the last tick.

This script shows the difference between pausing a “normal” and a “smart” timer:

package {
	import flash.display.Sprite;
	import flash.utils.Timer;
	import flash.utils.getTimer;
	import flash.events.TimerEvent;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.events.Event;
	import flash.text.TextFieldAutoSize;
	public class pauseTimer extends Sprite {
		// the interval between two ticks, in milliseconds
		private var interval:int=1000;
		// the "normal" timer
		private var normalTimer:Timer;
		// the "smart" timer
		private var smartTimer:Timer;
		// just some text field related variables
		private var normalTimerText:TextField = new TextField();
		private var smartTimerText:TextField = new TextField();
		private var normalTextFormat:TextFormat = new TextFormat();
		private var smartTextFormat:TextFormat = new TextFormat();
		// the "movie paused" screen
		private var pausedScreen:pausedMc=new pausedMc();
		// variables used to handle the smart timer
		private var lapTime:Number=0;
		private var currentTimer:Number=0;
		public function pauseTimer() {
			// nothing interesting, only some layout settings
			normalTextFormat.size=24;
			normalTextFormat.color=0xA90000;
			smartTextFormat.size=24;
			smartTextFormat.color=0x00A900;
			addChild(normalTimerText);
			normalTimerText.autoSize=TextFieldAutoSize.LEFT;
			addChild(smartTimerText);
			smartTimerText.autoSize=TextFieldAutoSize.LEFT;
			addChild(pausedScreen);
			smartTimerText.y=50;
			// timer initialization
			normalTimer=new Timer(interval);
			smartTimer=new Timer(interval);
			// timer listeners
			normalTimer.addEventListener(TimerEvent.TIMER, showNormalTime);
			smartTimer.addEventListener(TimerEvent.TIMER, showSmartTime);
			// activate/deactivate listeners
			addEventListener(Event.ACTIVATE,onActivate);
			addEventListener(Event.DEACTIVATE,onDeactivate);
		}
		private function showNormalTime(e:TimerEvent):void {
			// just showing the number of ticks
			normalTimerText.text="Normal counter: "+normalTimer.currentCount+" ticks counted";
			normalTimerText.setTextFormat(normalTextFormat);
		}
		private function showSmartTime(e:TimerEvent):void {
			// set the delay to "interval" value if it has a different value (it will happen)
			if (smartTimer.delay!=interval) {
				smartTimer.delay=interval;
			}
			// saving the current timer
			currentTimer=getTimer();
			smartTimerText.text="Smart counter: "+smartTimer.currentCount+" ticks counted";
			smartTimerText.setTextFormat(smartTextFormat);
		}
		private function onActivate(e:Event):void {
			pausedScreen.visible=false;
			// smart timer delay management
			if (smartTimer.delay-lapTime>0) {
				smartTimer.delay=smartTimer.delay-lapTime;
			}
			// saving the curren time
			currentTimer=getTimer();
			// starting the timers
			normalTimer.start();
			smartTimer.start();
		}
		private function onDeactivate(e:Event):void {
			pausedScreen.visible=true;
			// stopping the timers
			normalTimer.stop();
			smartTimer.stop();
			// determining how much time has passed since the last tick
			lapTime=(getTimer()-currentTimer);
			smartTimerText.text="Smart counter: "+smartTimer.currentCount+" ticks counted and "+(smartTimer.delay-lapTime)+"ms to next tick";
			smartTimerText.setTextFormat(smartTextFormat);
		}
	}
}

And this is the result:

Try to pause and un pause the movie very quickly, clicking inside and outside it, to see how the normal timer never gets triggered while the smart timer does.

Download the source code.

Get the most popular Phaser 3 book

Through 202 pages, 32 source code examples and an Android Studio project you will learn how to build cross platform HTML5 games and create a complete game along the way.

Get the book

215 GAME PROTOTYPES EXPLAINED WITH SOURCE CODE
// 1+2=3
// 100 rounds
// 10000000
// 2 Cars
// 2048
// A Blocky Christmas
// A Jumping Block
// A Life of Logic
// Angry Birds
// Angry Birds Space
// Artillery
// Astro-PANIC!
// Avoider
// Back to Square One
// Ball Game
// Ball vs Ball
// Ball: Revamped
// Balloon Invasion
// BallPusher
// Ballz
// Bar Balance
// Bejeweled
// Biggification
// Block it
// Blockage
// Bloons
// Boids
// Bombuzal
// Boom Dots
// Bouncing Ball
// Bouncing Ball 2
// Bouncy Light
// BoxHead
// Breakout
// Bricks
// Bubble Chaos
// Bubbles 2
// Card Game
// Castle Ramble
// Chronotron
// Circle Chain
// Circle Path
// Circle Race
// Circular endless runner
// Cirplosion
// CLOCKS - The Game
// Color Hit
// Color Jump
// ColorFill
// Columns
// Concentration
// Crossy Road
// Crush the Castle
// Cube Jump
// CubesOut
// Dash N Blast
// Dashy Panda
// Deflection
// Diamond Digger Saga
// Don't touch the spikes
// Dots
// Down The Mountain
// Drag and Match
// Draw Game
// Drop Wizard
// DROP'd
// Dudeski
// Dungeon Raid
// Educational Game
// Elasticity
// Endless Runner
// Erase Box
// Eskiv
// Farm Heroes Saga
// Filler
// Flappy Bird
// Fling
// Flipping Legend
// Floaty Light
// Fuse Ballz
// GearTaker
// Gem Sweeper
// Globe
// Goat Rider
// Gold Miner
// Grindstone
// GuessNext
// Helicopter
// Hero Emblems
// Hero Slide
// Hexagonal Tiles
// HookPod
// Hop Hop Hop Underwater
// Horizontal Endless Runner
// Hundreds
// Hungry Hero
// Hurry it's Christmas
// InkTd
// Iromeku
// Jet Set Willy
// Jigsaw Game
// Knife Hit
// Knightfall
// Legends of Runeterra
// Lep's World
// Line Rider
// Lumines
// Magick
// MagOrMin
// Mass Attack
// Math Game
// Maze
// Meeblings
// Memdot
// Metro Siberia Underground
// Mike Dangers
// Mikey Hooks
// Nano War
// Nodes
// o:anquan
// One Button Game
// One Tap RPG
// Ononmin
// Pacco
// Perfect Square!
// Perfectionism
// Phyballs
// Pixel Purge
// PixelField
// Planet Revenge
// Plants Vs Zombies
// Platform
// Platform game
// Plus+Plus
// Pocket Snap
// Poker
// Pool
// Pop the Lock
// Pop to Save
// Poux
// Pudi
// Pumpkin Story
// Puppet Bird
// Pyramids of Ra
// qomp
// Quick Switch
// Racing
// Radical
// Rebuild Chile
// Renju
// Rise Above
// Risky Road
// Roguelike
// Roly Poly
// Run Around
// Rush Hour
// SameGame
// SamePhysics
// Save the Totem
// Security
// Serious Scramblers
// Shrink it
// Sling
// Slingy
// Snowflakes
// Sokoban
// Space Checkers
// Space is Key
// Spellfall
// Spinny Gun
// Splitter
// Spring Ninja
// Sproing
// Stabilize!
// Stack
// Stairs
// Stick Hero
// String Avoider
// Stringy
// Sudoku
// Super Mario Bros
// Surfingers
// Survival Horror
// Talesworth Adventure
// Tetris
// The Impossible Line
// The Moops - Combos of Joy
// The Next Arrow
// Threes
// Tic Tac Toe
// Timberman
// Tiny Wings
// Tipsy Tower
// Toony
// Totem Destroyer
// Tower Defense
// Trick Shot
// Tunnelball
// Turn
// Turnellio
// TwinSpin
// vvvvvv
// Warp Shift
// Way of an Idea
// Whack a Creep
// Wheel of Fortune
// Where's my Water
// Wish Upon a Star
// Word Game
// Wordle
// Worms
// Yanga
// Yeah Bunny
// Zhed
// zNumbers