| OLD | NEW |
| (Empty) |
| 1 part of game; | |
| 2 | |
| 3 class _Audio { | |
| 4 static const List<String> _AUDIO_NAMES = | |
| 5 const ['Pop0', 'Pop1', 'Pop2', 'Pop3', 'Pop4', 'Pop5', 'Pop6', 'Pop7', 'Po
p8', | |
| 6 'Bomb0', 'Bomb1', 'Bomb2', 'Bomb3', 'Bomb4', | |
| 7 GameAudio.THROW_DART, GameAudio.FLAG, GameAudio.UNFLAG, GameAudio.C
LICK, GameAudio.WIN]; | |
| 8 | |
| 9 final AudioLoader _audioLoader; | |
| 10 final Map<String, AudioBuffer> _buffers = new Map(); | |
| 11 static final _audioFormat = _getAudioFormat(); | |
| 12 | |
| 13 factory _Audio() { | |
| 14 if(_audioFormat != null) { | |
| 15 try { | |
| 16 final audioContext = new AudioContext(); | |
| 17 final loader = new AudioLoader(audioContext, _getAudioPaths(_AUDIO_NAMES
)); | |
| 18 return new _Audio._internal(loader); | |
| 19 } catch (e) { | |
| 20 print("Error creating AudioContext: ${e}"); | |
| 21 } | |
| 22 } | |
| 23 return new _Audio._disabled(); | |
| 24 } | |
| 25 | |
| 26 _Audio._disabled() : this._audioLoader = null; | |
| 27 | |
| 28 _Audio._internal(this._audioLoader) { | |
| 29 // TODO: less than ideal. Binding to event handlers defined in game.dart | |
| 30 // re-expose events? Take in handlers in ctor? Hmm... | |
| 31 _audioLoader.progress.listen(_onProgress); | |
| 32 _audioLoader.loaded.listen(_onLoaded); | |
| 33 _audioLoader.loaded.listen(_onLoad); | |
| 34 GameAudio.audioEvent.listen(_playAudio); | |
| 35 _audioLoader.load(); | |
| 36 } | |
| 37 | |
| 38 int get completedBytes { | |
| 39 if(_audioLoader == null) { | |
| 40 return 0; | |
| 41 } else { | |
| 42 return _audioLoader.completedBytes; | |
| 43 } | |
| 44 } | |
| 45 | |
| 46 int get totalBytes { | |
| 47 if(_audioLoader == null) { | |
| 48 return 0; | |
| 49 } else { | |
| 50 return _audioLoader.totalBytes; | |
| 51 } | |
| 52 } | |
| 53 | |
| 54 bool get done { | |
| 55 if(_audioLoader == null) { | |
| 56 return true; | |
| 57 } else { | |
| 58 return _audioLoader.state == ResourceLoader.StateLoaded; | |
| 59 } | |
| 60 } | |
| 61 | |
| 62 AudioContext get _audioContext { | |
| 63 if(_audioLoader != null) { | |
| 64 return _audioLoader.context; | |
| 65 } else { | |
| 66 return null; | |
| 67 } | |
| 68 } | |
| 69 | |
| 70 void _onLoad(args) { | |
| 71 assert(_buffers.length == 0); | |
| 72 for(final name in _AUDIO_NAMES) { | |
| 73 final path = _getAudioPath(name); | |
| 74 _buffers[name] = _audioLoader.getResource(path); | |
| 75 } | |
| 76 } | |
| 77 | |
| 78 void _playAudio(String name) { | |
| 79 switch(name) { | |
| 80 case GameAudio.POP: | |
| 81 final i = rnd.nextInt(8); | |
| 82 name = '${GameAudio.POP}$i'; | |
| 83 break; | |
| 84 case GameAudio.BOMB: | |
| 85 final i = rnd.nextInt(4); | |
| 86 name = '${GameAudio.BOMB}$i'; | |
| 87 break; | |
| 88 } | |
| 89 _playAudioCore(name); | |
| 90 } | |
| 91 | |
| 92 void _playAudioCore(String name) { | |
| 93 if(_audioContext != null) { | |
| 94 var source = _audioContext.createBufferSource(); | |
| 95 final buffer = _buffers[name]; | |
| 96 assert(buffer != null); | |
| 97 source.buffer = buffer; | |
| 98 source.connectNode(_audioContext.destination); | |
| 99 source.start(0); | |
| 100 } | |
| 101 } | |
| 102 | |
| 103 static String _getAudioFormat() { | |
| 104 try { | |
| 105 final userAgent = window.navigator.userAgent; | |
| 106 final isWebKit = userAgent.contains("WebKit"); | |
| 107 if(isWebKit) { | |
| 108 final isChrome = userAgent.contains("Chrome"); | |
| 109 if(isChrome) { | |
| 110 return 'webm'; | |
| 111 } else { | |
| 112 return 'm4a'; | |
| 113 } | |
| 114 } | |
| 115 } catch (e) { | |
| 116 print("Error getting client info: ${e}"); | |
| 117 } | |
| 118 return null; | |
| 119 } | |
| 120 | |
| 121 static String _getAudioPath(String name) { | |
| 122 assert(_audioFormat != null); | |
| 123 return 'audio/${_audioFormat}/$name.${_audioFormat}'; | |
| 124 } | |
| 125 | |
| 126 static Iterable<String> _getAudioPaths(Iterable<String> names) { | |
| 127 return names.map(_getAudioPath); | |
| 128 } | |
| 129 } | |
| OLD | NEW |