import * as Phaser from "phaser"; import { DRAG_SPEED_MIN_MULTIPLIER, DRAG_SPEED_MAX_MULTIPLIER, } from "../../GameConfig"; import { safePlaySound } from "../../utils/SoundUtils"; import { ENABLE_BACKGROUND_MUSIC } from "../../DebugConfig"; /** 拖拽速度值类型,范围 0.0 ~ 1.0 */ export type DragSpeedValue = number; /** * 设置管理器(单例)。 * 管理音乐、音效开关、拖拽速度和背景音乐播放。 */ export class SettingsManager { private static _instance: SettingsManager | null = null; public musicOn = true; public soundOn = true; /** 拖拽速度:0.0 = 慢, 1.0 = 快 */ public dragSpeed: DragSpeedValue = 0.5; private bgm: Phaser.Sound.BaseSound | null = null; private isBgmLoading = false; static get instance(): SettingsManager { if (!this._instance) { this._instance = new SettingsManager(); } return this._instance; } private constructor() {} /** * 播放按钮点击音效。 * @param scene 当前场景 */ public playButtonClick(scene: Phaser.Scene) { if (!this.soundOn) return; safePlaySound(scene, "button_click", { volume: 0.8 }); } /** * 播放背景音乐。如果音频尚未加载,会动态加载后再播放。 * @param scene 当前场景 */ public playBgm(scene: Phaser.Scene) { // 如果配置禁用背景音乐,直接返回 if (!ENABLE_BACKGROUND_MUSIC) { return; } if (!this.musicOn) { this.stopBgm(); return; } const soundManager = scene.sound; /** 开始播放背景音乐 */ const startPlay = () => { if (!this.musicOn) { return; } if (!this.bgm) { this.bgm = soundManager.add("bg"); } if (!this.bgm) { return; } this.bgm.stop(); this.bgm.play({ loop: true, volume: 0.45 }); }; // 如果音频已经在缓存中,直接播放 if (scene.cache.audio.exists("bg")) { startPlay(); return; } // 尚未加载且已经在加载中:避免重复发起请求 if (this.isBgmLoading) { return; } // 动态加载 bg.mp3,加载完成后根据当前开关决定是否播放 this.isBgmLoading = true; scene.load.once(Phaser.Loader.Events.COMPLETE, () => { this.isBgmLoading = false; if (this.musicOn) { startPlay(); } }); scene.load.start(); } /** 停止背景音乐 */ public stopBgm() { if (this.bgm) { this.bgm.stop(); } } /** * 将当前的音乐/音效设置应用到指定场景的声音系统。 * 通过 mute / volume 控制整体开关。 * @param scene 当前场景 */ public applyToSceneSound(scene: Phaser.Scene) { const soundManager = scene.sound; // musicOn 控制全局背景音乐是否允许播放;这里用 mute 简单实现 soundManager.mute = !this.soundOn && !this.musicOn; } /** * 根据 dragSpeed(0~1)返回拖拽速度倍率: * - dragSpeed = 0 -> 最小倍率 * - dragSpeed = 0.5 -> 默认速度 * - dragSpeed = 1 -> 最大倍率 * @returns 拖拽速度倍率 */ public getDragSpeedMultiplier(): number { const t = Phaser.Math.Clamp(this.dragSpeed, 0, 1); const factor = DRAG_SPEED_MIN_MULTIPLIER + t * (DRAG_SPEED_MAX_MULTIPLIER - DRAG_SPEED_MIN_MULTIPLIER); return factor; } }