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);
}
}
}