140 lines
3.7 KiB
TypeScript
140 lines
3.7 KiB
TypeScript
|
|
import { _decorator, Component, Node, AudioSource, AudioClip, director } from 'cc';
|
|||
|
|
const { ccclass, property } = _decorator;
|
|||
|
|
|
|||
|
|
// 背景音乐类型
|
|||
|
|
export enum BGMType {
|
|||
|
|
Home,
|
|||
|
|
Level,
|
|||
|
|
Boss,
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 音效类型
|
|||
|
|
export enum SFXType {
|
|||
|
|
Remove,
|
|||
|
|
Success,
|
|||
|
|
Fail,
|
|||
|
|
Item,
|
|||
|
|
Victory,
|
|||
|
|
Magic,
|
|||
|
|
Shuffle,
|
|||
|
|
Hint
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@ccclass('AudioManager')
|
|||
|
|
export class AudioManager extends Component {
|
|||
|
|
private static _instance: AudioManager | null = null;
|
|||
|
|
public static get instance(): AudioManager {
|
|||
|
|
if (!this._instance) {
|
|||
|
|
const node = new Node('AudioManager');
|
|||
|
|
this._instance = node.addComponent(AudioManager);
|
|||
|
|
director.addPersistRootNode(node);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return this._instance;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// AudioSources
|
|||
|
|
private bgmSource!: AudioSource;
|
|||
|
|
private sfxSource!: AudioSource;
|
|||
|
|
|
|||
|
|
// 开关
|
|||
|
|
public bgmEnabled: boolean = true;
|
|||
|
|
public sfxEnabled: boolean = true;
|
|||
|
|
|
|||
|
|
// 音乐 / 音效 Map
|
|||
|
|
private bgmClips: Map<BGMType, AudioClip> = new Map();
|
|||
|
|
private sfxClips: Map<SFXType, AudioClip> = new Map();
|
|||
|
|
|
|||
|
|
private currentBGM: BGMType | null = null;
|
|||
|
|
|
|||
|
|
onLoad() {
|
|||
|
|
// 初始化单例
|
|||
|
|
AudioManager._instance = this;
|
|||
|
|
|
|||
|
|
// 跨场景不销毁
|
|||
|
|
// director.addPersistRootNode(this.node);
|
|||
|
|
|
|||
|
|
// 读取本地开关
|
|||
|
|
this.bgmEnabled = localStorage.getItem('bgmEnabled') !== '0';
|
|||
|
|
this.sfxEnabled = localStorage.getItem('sfxEnabled') !== '0';
|
|||
|
|
|
|||
|
|
// 自动挂载或创建 AudioSource
|
|||
|
|
const sources = this.node.getComponents(AudioSource);
|
|||
|
|
if (sources.length >= 2) {
|
|||
|
|
this.bgmSource = sources[0];
|
|||
|
|
this.sfxSource = sources[1];
|
|||
|
|
} else {
|
|||
|
|
this.bgmSource = this.node.addComponent(AudioSource);
|
|||
|
|
this.bgmSource.loop = true;
|
|||
|
|
this.sfxSource = this.node.addComponent(AudioSource);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/** 注册 BGM */
|
|||
|
|
public registerBGM(type: BGMType, clip: AudioClip) {
|
|||
|
|
this.bgmClips.set(type, clip);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/** 注册 SFX */
|
|||
|
|
public registerSFX(type: SFXType, clip: AudioClip) {
|
|||
|
|
this.sfxClips.set(type, clip);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/** 播放背景音乐 */
|
|||
|
|
public playBGM(type: BGMType) {
|
|||
|
|
if (!this.bgmEnabled) return;
|
|||
|
|
// if (this.currentBGM === type) return;
|
|||
|
|
|
|||
|
|
const clip = this.bgmClips.get(type);
|
|||
|
|
if (!clip) return;
|
|||
|
|
|
|||
|
|
this.currentBGM = type;
|
|||
|
|
this.bgmSource.clip = clip;
|
|||
|
|
this.bgmSource.loop = true;
|
|||
|
|
this.bgmSource.play();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/** 播放音效 */
|
|||
|
|
public playSFX(type: SFXType) {
|
|||
|
|
if (!this.sfxEnabled) return;
|
|||
|
|
|
|||
|
|
const clip = this.sfxClips.get(type);
|
|||
|
|
if (!clip) return;
|
|||
|
|
|
|||
|
|
this.sfxSource.playOneShot(clip, 1.0);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/** 设置 BGM 开关 */
|
|||
|
|
public setBGMEnabled(enabled: boolean) {
|
|||
|
|
this.bgmEnabled = enabled;
|
|||
|
|
localStorage.setItem('bgmEnabled', enabled ? '1' : '0');
|
|||
|
|
if (!this.bgmSource) return;
|
|||
|
|
|
|||
|
|
if (enabled) {
|
|||
|
|
// 开启播放当前 BGM
|
|||
|
|
if (this.currentBGM !== null || this.currentBGM !== undefined) {
|
|||
|
|
const clip = this.bgmClips.get(this.currentBGM);
|
|||
|
|
if (clip) {
|
|||
|
|
this.bgmSource.clip = clip;
|
|||
|
|
this.bgmSource.play();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
// 关闭停止播放
|
|||
|
|
this.bgmSource.stop();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/** 设置 SFX 开关 */
|
|||
|
|
public setSFXEnabled(enabled: boolean) {
|
|||
|
|
this.sfxEnabled = enabled;
|
|||
|
|
localStorage.setItem('sfxEnabled', enabled ? '1' : '0');
|
|||
|
|
// 关闭音效后,playSFX 会直接返回,不会播放
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/** 设置 SFX 开关 */
|
|||
|
|
public setCurBgm(type: number) {
|
|||
|
|
this.currentBGM = type;
|
|||
|
|
}
|
|||
|
|
}
|