first commit
This commit is contained in:
139
assets/scripts/AudioManager.ts
Normal file
139
assets/scripts/AudioManager.ts
Normal file
@@ -0,0 +1,139 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user