2024-03-06 01:28:01 -08:00
|
|
|
import { _decorator, AudioClip, AudioSource, Component, Node } from 'cc';
|
2024-03-28 20:35:44 -07:00
|
|
|
import Singleton from '../Singleton';
|
2024-04-24 04:05:06 -07:00
|
|
|
import { Howl } from 'howler';
|
2024-03-06 01:28:01 -08:00
|
|
|
const { ccclass, property } = _decorator;
|
|
|
|
|
2024-04-25 02:23:23 -07:00
|
|
|
export class SoundSource {
|
2024-03-06 01:28:01 -08:00
|
|
|
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;
|
|
|
|
}
|
2024-04-03 02:43:18 -07:00
|
|
|
|
|
|
|
this._mute = value;
|
2024-03-06 01:28:01 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
public play() {
|
2024-04-03 02:43:18 -07:00
|
|
|
if (this.source.playing) {
|
|
|
|
this.source.playOneShot(this.source.clip, this.mute ? 0 : this.volume);
|
|
|
|
return;
|
|
|
|
}
|
2024-03-06 01:28:01 -08:00
|
|
|
this.source.play();
|
|
|
|
}
|
|
|
|
|
|
|
|
public stop() {
|
|
|
|
this.source.stop();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@ccclass('SoundManager')
|
2024-03-28 20:35:44 -07:00
|
|
|
export class SoundManager extends Singleton<SoundManager>('SoundManager') {
|
2024-03-06 01:28:01 -08:00
|
|
|
private _audioSourcesSfx: { [key: string]: SoundSource } = {};
|
2024-04-24 04:05:06 -07:00
|
|
|
private _audioSourceBgm: Howl;
|
2024-03-06 01:28:01 -08:00
|
|
|
|
2024-04-03 02:43:18 -07:00
|
|
|
private _isMute = false;
|
2024-03-06 01:28:01 -08:00
|
|
|
|
|
|
|
public toggleMute(): boolean {
|
2024-04-03 02:43:18 -07:00
|
|
|
this._isMute = !this._isMute;
|
|
|
|
this.setMute(this._isMute);
|
|
|
|
return this._isMute;
|
2024-03-06 01:28:01 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
public setMute(mute: boolean) {
|
2024-04-03 02:43:18 -07:00
|
|
|
this._isMute = mute;
|
2024-04-24 04:05:06 -07:00
|
|
|
this._audioSourceBgm.mute(this._isMute);
|
2024-03-06 01:28:01 -08:00
|
|
|
for (const key in this._audioSourcesSfx) {
|
2024-04-03 02:43:18 -07:00
|
|
|
this._audioSourcesSfx[key].mute = this._isMute;
|
2024-03-06 01:28:01 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-25 02:23:23 -07:00
|
|
|
public playBGM(audio: AudioClip, opts?: { volume?: number; loop?: boolean; rate?: number }) {
|
2024-04-24 04:05:06 -07:00
|
|
|
this._audioSourceBgm?.stop();
|
|
|
|
this._audioSourceBgm = new globalThis.Howl({
|
|
|
|
src: audio.nativeUrl,
|
2024-04-25 02:23:23 -07:00
|
|
|
volume: opts?.volume || 1,
|
2024-04-25 02:29:49 -07:00
|
|
|
loop: opts?.loop || true,
|
2024-04-25 02:23:23 -07:00
|
|
|
rate: opts?.rate || 1,
|
2024-04-24 04:05:06 -07:00
|
|
|
mute: this._isMute,
|
|
|
|
});
|
2024-03-06 01:28:01 -08:00
|
|
|
this._audioSourceBgm.play();
|
|
|
|
}
|
|
|
|
|
2024-04-24 04:05:06 -07:00
|
|
|
public setPlayRateBGM(rate: number) {
|
|
|
|
this._audioSourceBgm.rate(rate);
|
|
|
|
}
|
|
|
|
|
2024-04-25 02:23:23 -07:00
|
|
|
public playSfx(audioClip: AudioClip, opts?: { volume?: number; loop?: boolean }) {
|
2024-03-06 01:28:01 -08:00
|
|
|
let soundSource = this._audioSourcesSfx[audioClip.uuid];
|
2024-03-11 04:12:22 -07:00
|
|
|
|
2024-03-06 01:28:01 -08:00
|
|
|
if (soundSource) {
|
2024-04-25 02:23:23 -07:00
|
|
|
soundSource.volume = opts?.volume || 1;
|
|
|
|
soundSource.source.loop = !!opts?.loop;
|
|
|
|
if (soundSource.source.playing && !!opts?.loop) return;
|
2024-03-06 01:28:01 -08:00
|
|
|
soundSource.play();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
soundSource = new SoundSource();
|
|
|
|
const audioSource = new AudioSource('audioSourceSfx:' + audioClip.name);
|
|
|
|
soundSource.source = audioSource;
|
|
|
|
soundSource.source.playOnAwake = false;
|
|
|
|
soundSource.source.clip = audioClip;
|
2024-04-25 02:23:23 -07:00
|
|
|
soundSource.source.loop = !!opts?.loop;
|
|
|
|
soundSource.source.volume = opts?.volume || 1;
|
2024-04-03 02:43:18 -07:00
|
|
|
soundSource.mute = this._isMute;
|
2024-03-06 01:28:01 -08:00
|
|
|
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];
|
|
|
|
}
|
|
|
|
}
|