178 lines
4.5 KiB
TypeScript
178 lines
4.5 KiB
TypeScript
import { _decorator, AudioClip, AudioSource } from 'cc';
|
|
|
|
interface ISoundOptions {
|
|
volume?: number;
|
|
loop?: boolean;
|
|
playbackRate?: number;
|
|
}
|
|
|
|
export class SoundSource {
|
|
private _source: AudioSource;
|
|
|
|
public get playing() {
|
|
return this._source.playing;
|
|
}
|
|
|
|
public get loop() {
|
|
return this._source.loop;
|
|
}
|
|
|
|
public set loop(value: boolean) {
|
|
this._source.loop = value;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
this._mute = value;
|
|
}
|
|
|
|
public get clip() {
|
|
return this._source.clip;
|
|
}
|
|
|
|
public set clip(value: AudioClip) {
|
|
this._source.clip = value;
|
|
}
|
|
|
|
public get playbackRate() {
|
|
return this._source.getPlaybackRate();
|
|
}
|
|
|
|
public set playbackRate(value: number) {
|
|
this._source.setPlaybackRate(value);
|
|
}
|
|
|
|
constructor(audioClip: AudioClip) {
|
|
this._source = new AudioSource();
|
|
this._source.playOnAwake = false;
|
|
this._source.clip = audioClip;
|
|
}
|
|
|
|
public play() {
|
|
if (!this.loop) {
|
|
if (this.playing) {
|
|
this._source.playOneShot(this._source.clip, this.mute ? 0 : this.volume);
|
|
return;
|
|
}
|
|
this._source.play();
|
|
} else {
|
|
if (!this.playing) this._source.play();
|
|
}
|
|
}
|
|
|
|
public stop() {
|
|
this._source.stop();
|
|
}
|
|
}
|
|
|
|
export default class AudioManager {
|
|
private static readonly storageKey = 'gad-game-galaxy-seeker-mute';
|
|
private static _audioSourcesSfx: Map<AudioClip, SoundSource> = new Map();
|
|
private static _audioSourceBgm: SoundSource;
|
|
private static _isMute: boolean = false;
|
|
|
|
public static get mute() {
|
|
return this._isMute;
|
|
}
|
|
|
|
public static toggleMute(): boolean {
|
|
this._isMute = !this._isMute;
|
|
this.setMute(this._isMute);
|
|
return this._isMute;
|
|
}
|
|
|
|
public static setMute(mute: boolean) {
|
|
this._audioSourceBgm.mute = mute;
|
|
this._audioSourcesSfx.forEach((source) => {
|
|
source.mute = mute;
|
|
});
|
|
|
|
this._isMute = mute;
|
|
}
|
|
|
|
public static playBGM(audio: AudioClip, opts?: ISoundOptions) {
|
|
const config: ISoundOptions = {
|
|
volume: 1,
|
|
loop: true,
|
|
playbackRate: 1,
|
|
...opts,
|
|
};
|
|
if (this._audioSourceBgm) {
|
|
this._audioSourceBgm.stop();
|
|
this._audioSourceBgm.clip = audio;
|
|
} else {
|
|
this._audioSourceBgm = new SoundSource(audio);
|
|
}
|
|
this._audioSourceBgm.loop = config.loop;
|
|
this._audioSourceBgm.volume = config.volume;
|
|
this._audioSourceBgm.mute = this._isMute;
|
|
this._audioSourceBgm.play();
|
|
this._audioSourceBgm.playbackRate = config.playbackRate;
|
|
}
|
|
|
|
public static setPlayRateBGM(rate: number) {
|
|
this._audioSourceBgm.playbackRate = rate;
|
|
}
|
|
|
|
public static playSfx(audioClip: AudioClip, opts?: ISoundOptions) {
|
|
let soundSource = this._audioSourcesSfx.get(audioClip);
|
|
const config: ISoundOptions = {
|
|
volume: 1,
|
|
loop: false,
|
|
playbackRate: 1,
|
|
...opts,
|
|
};
|
|
|
|
if (soundSource) {
|
|
soundSource.volume = config.volume;
|
|
soundSource.loop = config.loop;
|
|
soundSource.mute = this._isMute;
|
|
soundSource.play();
|
|
return;
|
|
}
|
|
|
|
soundSource = new SoundSource(audioClip);
|
|
soundSource.loop = config.loop;
|
|
soundSource.volume = config.volume;
|
|
soundSource.mute = this._isMute;
|
|
this._audioSourcesSfx.set(audioClip, soundSource);
|
|
soundSource.play();
|
|
}
|
|
|
|
public static stopBgm() {
|
|
this._audioSourceBgm.stop();
|
|
}
|
|
|
|
public static stopSfx(audioClip: AudioClip) {
|
|
this._audioSourcesSfx.get(audioClip).stop();
|
|
}
|
|
|
|
public static stopAllSfxLoop() {
|
|
this._audioSourcesSfx.forEach((sfx) => sfx.stop());
|
|
}
|
|
|
|
public static findAudioSourcesSfx(audioClip: AudioClip): SoundSource {
|
|
return this._audioSourcesSfx.get(audioClip);
|
|
}
|
|
}
|