import { _decorator, AudioClip, AudioSource, Component, Node } from 'cc'; const { ccclass, property } = _decorator; class SoundSource { public source: AudioSource; private _volume = 1; public get volume() { return this._volume; } public set volume(value: number) { this._volume = value; if (!this.mute) this.source.volume = value; } private _mute = false; public get mute() { return this._mute; } public set mute(value: boolean) { if (value) { this.source.volume = 0; } else { this.source.volume = this.volume; } } public play() { this.source.play(); } public stop() { this.source.stop(); } } @ccclass('SoundManager') export class SoundManager extends Component { //singleton private static _instance: SoundManager; public static get instance(): SoundManager { if (!SoundManager._instance) { SoundManager._instance = new SoundManager('SoundManager'); } return SoundManager._instance; } private _audioSourcesSfx: { [key: string]: SoundSource } = {}; private _audioSourceBgm: SoundSource; private isMute = false; protected onLoad(): void { SoundManager._instance = this; } public toggleMute(): boolean { this.isMute = !this.isMute; this.setMute(this.isMute); return this.isMute; } public setMute(mute: boolean) { this.isMute = mute; this._audioSourceBgm.mute = this.isMute; for (const key in this._audioSourcesSfx) { this._audioSourcesSfx[key].mute = this.isMute; } } public playBGM(audio: AudioClip, volume = 1, loop = true) { if (!this._audioSourceBgm) { this._audioSourceBgm = new SoundSource(); this._audioSourceBgm.source = new AudioSource('audioSourceBgm'); this._audioSourceBgm.source.playOnAwake = false; } this._audioSourceBgm.stop(); this._audioSourceBgm.volume = volume; this._audioSourceBgm.source.clip = audio; this._audioSourceBgm.source.loop = loop; this._audioSourceBgm.mute = this.isMute; this._audioSourceBgm.play(); } public playSfx(audioClip: AudioClip, volume = 1, loop = false) { let soundSource = this._audioSourcesSfx[audioClip.uuid]; if (soundSource) { soundSource.volume = volume; soundSource.source.loop = loop; if (loop) return; if (soundSource.source.playing) { soundSource.source.playOneShot(audioClip, this.isMute ? 0 : volume); return; } soundSource.play(); return; } soundSource = new SoundSource(); const audioSource = new AudioSource('audioSourceSfx:' + audioClip.name); soundSource.source = audioSource; soundSource.source.playOnAwake = false; soundSource.source.clip = audioClip; soundSource.source.loop = loop; soundSource.source.volume = volume; soundSource.mute = this.isMute; this._audioSourcesSfx[audioClip.uuid] = soundSource; soundSource.play(); } public stopBgm() { this._audioSourceBgm.stop(); } public stopSfx(audioClip: AudioClip) { this._audioSourcesSfx[audioClip.uuid].stop(); } public stopAllSfxLoop() { for (const key in this._audioSourcesSfx) { this._audioSourcesSfx[key].stop(); } } public findAudioSourcesSfx(audioClip: AudioClip): SoundSource { return this._audioSourcesSfx[audioClip.uuid]; } }