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 = new Map(); private sfxClips: Map = 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; } }