Engine.SoundPlayer = class { get soundVolume() { return this._soundVolume; } set soundVolume(value) { this._soundVolume = Math.max(0, Math.min(value, 1)); for (var clip of Object.values(this.clips)) { if(clip != null && clip != this.bgMusic) { clip.volume = this._soundVolume; } } } get musicVolume() { return this._musicVolume; } set musicVolume(value) { this._musicVolume = Math.max(0, Math.min(value, 1)); if (this.bgMusic != null) this.bgMusic.volume = this._musicVolume; } constructor() { this._soundVolume = 1; this._musicVolume = 1; this.enabled = false; this.idTable = {};//new Dictionary<int, ISoundEffect>(); this.lastSoundPlayTime = {};//new Dictionary<string, long>(); this.bgMusic = null; this.volumeTween = new Engine.SimpleTween(); this.currentPlayingMusic = -1; this.players = [];//new List<GameObject>(); this.clips = {};//new Dictionary<string,AudioClip>(); } initialize() { this.enabled = true; if (this.bgMusic == null) return; else { this.bgMusic.play({"loop": true}) this.bgMusic.volume = this.musicVolume; } } playSound(id /*int*/, volumeScale /*float*/, oneShot /*bool*/) { if (volumeScale === undefined) volumeScale = 0.5; if (oneShot === undefined) oneShot = true; if (!this.enabled || this.soundVolume <= 0) return null; if (!this.idTable.hasOwnProperty(id)) return null; var playVolume = Math.clamp(this.idTable[id].volume, 0, 1) * volumeScale; this.getClipID(id, false, (clip) => this.loadedPlaySoundName(clip, oneShot, playVolume)); } loadedPlaySoundName(clip, oneShot, volume) { if (!this.enabled || clip == null || !clip.isLoaded) return null; if (!this.shouldPlaySound(clip.url)) return; this.lastSoundPlayTime[clip.url] = Engine.Utils.getTimer(); clip.play({"loop": !oneShot}); clip.volume = this.soundVolume * volume; } shouldPlaySound(name /*string*/) { if (!this.lastSoundPlayTime.hasOwnProperty(name)) { this.lastSoundPlayTime[name] = 0; } var now = Engine.Utils.getTimer(); var last = this.lastSoundPlayTime[name]; return (now - last) > 100; } playBGSound(id /*int*/) { this.getClipID(id, true, (bgMusic) => this.loadedPlayBGSound(bgMusic)); } loadedPlayBGSound(bgMusic) { this.bgMusic = bgMusic; if (!this.enabled || this.bgMusic == null || !this.bgMusic.isLoaded) return null; this.bgMusic.play({"loop": true}) this.bgMusic.volume = this.musicVolume; } changeBGMusic(id /*int*/, timeToFadeOut /*float*/) { if (timeToFadeOut === undefined) timeToFadeOut = 1; if (id == this.currentPlayingMusic) return this.bgMusic; this.currentPlayingMusic = id; if (this.bgMusic == null) { this.playBGSound(id); this.fadeInBGSound(id, timeToFadeOut); } else { this.fadeOutSound(this.bgMusic, timeToFadeOut, () => { this.fadeInBGSound(id, timeToFadeOut); }); } return this.bgMusic; } fadeOutSound(clip /*AudioSource*/, timeToFadeOut /*float*/, onFinish /*Action*/) { if (timeToFadeOut === undefined) timeToFadeOut = 3; if (onFinish === undefined) onFinish = null; if (clip == null || !clip.isPlaying) { onFinish(); return; } this.volumeTween.stop(); this.volumeTween.init((volume) => clip.volume = volume, Engine.SimpleTween.easeLinear, clip.volume, 0, timeToFadeOut); this.volumeTween.onFinish = () => { if (onFinish != null) onFinish(); }; } fadeInBGSound(id /*int*/, timeToFadeIn /*float*/, onFinish /*Action*/) { if (timeToFadeIn === undefined) timeToFadeIn = 3; if (onFinish === undefined) onFinish = null; if (this.bgMusic == null) { this.playBGSound(id); if (this.bgMusic == null) return null; } this.bgMusic.volume = 0; this.bgMusic.stop(); this.playBGSound(id); this.volumeTween.stop(); this.volumeTween.init((volume) => this.bgMusic.volume = volume, Engine.SimpleTween.easeLinear, 0, this.musicVolume, timeToFadeIn); this.volumeTween.onFinish = () => { if (onFinish != null) onFinish(); }; return this.bgMusic; } getClipID(id /*int*/, isMusic, playCallback) { if (isMusic === undefined) isMusic = false; if (playCallback === undefined) playCallback = null; var name = ""; if (this.idTable.hasOwnProperty(id)) name = this.idTable[id].name; this.getClipName(name, isMusic, playCallback); } getClipName(name /*string*/, isMusic, playCallback) { if (isMusic === undefined) isMusic = false; if (playCallback === undefined) playCallback = null; var clip = null; if (this.clips.hasOwnProperty(name)) { playCallback(this.clips[name]); } else { this.clips[name] = null; PIXI.sound.Sound.from({ url: EngineSettings.LocalAssetRoot + "sounds/" + name + (isMusic ? ".mp3" : ".wav"), preload: true, loaded: (err, sound) => this.clipLoaded(err, sound, name, playCallback), singleInstance: true, }); } } clipLoaded(err, sound, name, playCallback) { if (err == null) { this.clips[name] = sound; playCallback(sound); } } }