First things first the theory https://gameprogrammingpatterns.com/singleton.html by Bob Nystrom aka @Munificentbob
Example implementation of the Singleton Pattern in AS3
SingletonSkeleton.as
package { public class SingletonSkeleton { static private var _instance:SingletonSkeleton; public function SingletonSkeleton( singletonLock:SingletonLock ) { } static public function get instance():SingletonSkeleton { if (!_instance) _instance = new SingletonSkeleton(new SingletonLock()); return _instance; } } } class SingletonLock { }
Here, the idea behind the SingletonLock Class is to hide the key in the box, if you want to open it you have to use the getter.
As a use case, I choose to illustrate the Singleton Pattern with a SoundManager. (Sorry Bob…)
package engine { import flash.media.Sound; import flash.media.SoundChannel; import flash.media.SoundMixer; import flash.media.SoundTransform; public class SoundManager { private const MAX_TRACK:int = 16; private var _tracks:Vector.<sound> = new Vector.<sound>(MAX_TRACK, true);</sound></sound> // singleton instance static private var _instance:SoundManager; // audio channel private var _channelBGM:SoundChannel = new SoundChannel; private var _channelSFX:SoundChannel = new SoundChannel; // tracks id public static const BIP:int = 0; public static const BGM1:int = 1; public static const BGM2:int = 2; public static const BGM3:int = 3; public static const BONUS1:int = 4; public static const BONUS2:int = 5; public static const BONUS3:int = 6; public static const BONUS4:int = 7; public static const ACTION1:int = 8; public static const ACTION2:int = 9; public static const ACTION3:int = 10; public static const ACTION4:int = 11; public static const SPECIAL1:int = 12; public static const SPECIAL2:int = 13; public static const SPECIAL3:int = 14; public static const SPECIAL4:int = 15; // private var _currentBgmIdx:int = -1; private var _paused:Boolean = false; private var _position:Number = .0; public function SoundManager(singletonLock:SingletonLock) { } static public function get instance():SoundManager { if (!_instance) _instance = new SoundManager(new SingletonLock()); return _instance; } public function addRessource(sound:Sound, idx:uint = ACTION1):void { if (idx < _tracks.length) { _tracks[idx] = sound; } else { throw new Error("ERROR: " + _tracks.length + " slots Max."); } } public function playSfx(idx:int = ACTION1):void { var s:Sound = _tracks[idx]; if (s == null) { throw new Error("ERROR: No ressource for track " + idx); } else { _channelSFX = s.play(0, 0, _channelSFX.soundTransform); } } public function playBGM(idx:int = BGM1, repeat:int = 999):void { var s:Sound = _tracks[idx]; if (s == null) { throw new Error("ERROR: No ressource for track " + idx); } else { if (idx != _currentBgmIdx) { _paused = false; _channelBGM.stop(); _currentBgmIdx = idx; _channelBGM = s.play(0, 999, _channelBGM.soundTransform); } } } // PAUSE/RESUME BGM public function pauseBGM():void { if (!_paused && _currentBgmIdx > -1) { _position = _channelBGM.position; _channelBGM.stop(); _paused = true; } } public function resumeBGM():void { if (_paused && _currentBgmIdx > -1) { _channelBGM = _tracks[_currentBgmIdx].play(_position, 999, _channelBGM.soundTransform); _paused = false; } } public function set bgmVolume(value:Number):void { if (value < 0) { value = 0; } _channelBGM.soundTransform = new SoundTransform(value); } public function get bgmVolume():Number { return _channelBGM.soundTransform.volume; } public function set sfxVolume(value:Number):void { if (value < 0) { value = 0; } _channelSFX.soundTransform = new SoundTransform(value); } public function get sfxVolume():Number { return _channelSFX.soundTransform.volume; } // STOP (not pause) EVERY SOUNDS public function stopAllSounds():void { _paused = false; _currentBgmIdx = -1; _position = .0; SoundMixer.stopAll(); } } } class SingletonLock { }
Usage
Step 1, embed your ressource
[Embed(source = "assets/Portal2-01-Science_is_Fun_part1.mp3")] private const BgmScienceClass:Class;
Step 2, create your sound ressource
SoundManager.instance.addRessource( new BgmScienceClass() , SoundManager.BGM1 );
Step 3, just play when needed
SoundManager.instance.playBGM( SoundManager.BGM1 );
Demo
Credits
BGM 1 »Portal 2 OST
BGM 2 »LoneWolf DS
SFX » bfxr