import { _decorator, Component, Node, Slider, Button, Sprite, SpriteFrame, ProgressBar, resources, tween, Vec3 } from 'cc'; import { AudioManager } from '../../AudioManager/AudioManager'; import { SaveDataManager } from '../../LevelSystem/SaveDataManager'; import { Audio } from '../../AudioManager/AudioManager'; const { ccclass, property } = _decorator; /** * 音频控制器 * 管理音效和音乐的音量控制以及开关状态 */ @ccclass('SoundController') export class SoundController extends Component { // 音效控制组件 @property({ type: Slider, tooltip: '音效音量滑动条' }) public soundEffectSlider: Slider = null; @property({ type: Button, tooltip: '音效开关按钮' }) public soundEffectCheckbox: Button = null; @property({ type: Node, tooltip: '音效勾选标记节点' }) public soundEffectCheck: Node = null; @property({ type: ProgressBar, tooltip: '音效进度条' }) public soundEffectProgressBar: ProgressBar = null; // 音乐控制组件 @property({ type: Slider, tooltip: '音乐音量滑动条' }) public musicSlider: Slider = null; @property({ type: Button, tooltip: '音乐开关按钮' }) public musicCheckbox: Button = null; @property({ type: Node, tooltip: '音乐勾选标记节点' }) public musicCheck: Node = null; @property({ type: ProgressBar, tooltip: '音乐进度条' }) public musicProgressBar: ProgressBar = null; // 震动控制组件 @property({ type: Button, tooltip: '震动开关按钮' }) public vibrationOnButton: Button = null; @property({ type: Button, tooltip: '震动关闭按钮' }) public vibrationOffButton: Button = null; @property({ type: Node, tooltip: '震动滑动节点' }) public vibrationSlideNode: Node = null; // 音量状态 private soundEffectEnabled: boolean = true; private musicEnabled: boolean = true; private savedSoundEffectVolume: number = 0.5; private savedMusicVolume: number = 0.5; private vibrationEnabled: boolean = true; onLoad() { this.initializeSliders(); this.bindEvents(); this.loadSettings(); } /** * 初始化滑动条 */ private initializeSliders() { if (this.soundEffectSlider) { this.soundEffectSlider.progress = this.savedSoundEffectVolume; this.updateProgressBar(this.soundEffectProgressBar, this.soundEffectSlider.progress); } if (this.musicSlider) { this.musicSlider.progress = this.savedMusicVolume; this.updateProgressBar(this.musicProgressBar, this.musicSlider.progress); } } /** * 绑定事件 */ private bindEvents() { // 音效滑动条事件 if (this.soundEffectSlider) { this.soundEffectSlider.node.on('slide', this.onSoundEffectSliderChange, this); } // 音乐滑动条事件 if (this.musicSlider) { this.musicSlider.node.on('slide', this.onMusicSliderChange, this); } // 音效开关按钮事件 if (this.soundEffectCheckbox) { this.soundEffectCheckbox.node.on(Button.EventType.CLICK, this.onSoundEffectCheckboxClick, this); } // 音乐开关按钮事件 if (this.musicCheckbox) { this.musicCheckbox.node.on(Button.EventType.CLICK, this.onMusicCheckboxClick, this); } // 震动开关按钮事件 if (this.vibrationOnButton) { this.vibrationOnButton.node.on(Button.EventType.CLICK, this.onVibrationOnClick, this); } if (this.vibrationOffButton) { this.vibrationOffButton.node.on(Button.EventType.CLICK, this.onVibrationOffClick, this); } } /** * 音效滑动条变化事件 */ private onSoundEffectSliderChange(slider: Slider) { if (this.soundEffectEnabled) { this.savedSoundEffectVolume = slider.progress; this.updateProgressBar(this.soundEffectProgressBar, slider.progress); // TODO: 应用音效音量到音频系统 this.applySoundEffectVolume(slider.progress); // 立即保存设置,确保退出前已落盘 this.saveSettings(); } } /** * 音乐滑动条变化事件 */ private onMusicSliderChange(slider: Slider) { if (this.musicEnabled) { this.savedMusicVolume = slider.progress; this.updateProgressBar(this.musicProgressBar, slider.progress); // TODO: 应用音乐音量到音频系统 this.applyMusicVolume(slider.progress); // 立即保存设置,确保退出前已落盘 this.saveSettings(); } } /** * 音效开关按钮点击事件 */ private onSoundEffectCheckboxClick() { Audio.playUISound('data/弹球音效/ui play'); this.soundEffectEnabled = !this.soundEffectEnabled; if (this.soundEffectEnabled) { // 开启音效:恢复之前保存的音量 this.soundEffectSlider.progress = this.savedSoundEffectVolume; this.updateProgressBar(this.soundEffectProgressBar, this.savedSoundEffectVolume); this.applySoundEffectVolume(this.savedSoundEffectVolume); } else { // 关闭音效:保存当前音量并设置为0 this.savedSoundEffectVolume = this.soundEffectSlider.progress; this.soundEffectSlider.progress = 0; this.updateProgressBar(this.soundEffectProgressBar, 0); this.applySoundEffectVolume(0); } // 更新勾选标记显示 if (this.soundEffectCheck) { this.soundEffectCheck.active = this.soundEffectEnabled; } this.saveSettings(); } /** * 音乐开关按钮点击事件 */ private onMusicCheckboxClick() { Audio.playUISound('data/弹球音效/ui play'); this.musicEnabled = !this.musicEnabled; if (this.musicEnabled) { // 开启音乐:恢复之前保存的音量 this.musicSlider.progress = this.savedMusicVolume; this.updateProgressBar(this.musicProgressBar, this.savedMusicVolume); this.applyMusicVolume(this.savedMusicVolume); } else { // 关闭音乐:保存当前音量并设置为0 this.savedMusicVolume = this.musicSlider.progress; this.musicSlider.progress = 0; this.updateProgressBar(this.musicProgressBar, 0); this.applyMusicVolume(0); } // 更新勾选标记显示 if (this.musicCheck) { this.musicCheck.active = this.musicEnabled; } this.saveSettings(); } /** * 震动开启按钮点击事件 */ private onVibrationOnClick() { Audio.playUISound('data/弹球音效/ui play'); this.vibrationEnabled = true; this.updateVibrationSlideButton(); this.saveVibrationSetting(); // 开启音效和音乐 this.enableSoundEffectAndMusic(); } /** * 震动关闭按钮点击事件 */ private onVibrationOffClick() { Audio.playUISound('data/弹球音效/ui play'); this.vibrationEnabled = false; this.updateVibrationSlideButton(); this.saveVibrationSetting(); // 关闭音效和音乐 this.disableSoundEffectAndMusic(); } /** * 更新震动滑动按钮位置 */ private updateVibrationSlideButton() { if (!this.vibrationSlideNode || !this.vibrationOnButton || !this.vibrationOffButton) { return; } // 获取目标按钮的位置 const targetButton = this.vibrationEnabled ? this.vibrationOnButton : this.vibrationOffButton; const targetPosition = targetButton.node.position.clone(); // 使用缓动动画移动滑动节点 tween(this.vibrationSlideNode) .to(0.3, { position: targetPosition }, { easing: 'sineInOut' }) .start(); } /** * 保存震动设置 */ private saveVibrationSetting() { const saveDataManager = SaveDataManager.getInstance(); if (saveDataManager) { saveDataManager.updateSetting('vibrationEnabled', this.vibrationEnabled); } } /** * 立即更新震动滑动按钮位置(不使用动画) */ private updateVibrationSlideButtonImmediate() { if (!this.vibrationSlideNode || !this.vibrationOnButton || !this.vibrationOffButton) { return; } // 获取目标按钮的位置 const targetButton = this.vibrationEnabled ? this.vibrationOnButton : this.vibrationOffButton; const targetPosition = targetButton.node.position.clone(); // 直接设置位置,不使用动画 this.vibrationSlideNode.position = targetPosition; } /** * 更新进度条显示 */ private updateProgressBar(progressBar: ProgressBar, progress: number) { if (!progressBar) return; // 直接设置ProgressBar的进度值 // ProgressBar会自动处理背景和前景的显示,保持黑色背景不变 progressBar.progress = progress; } /** * 应用音效音量到音频系统 */ private applySoundEffectVolume(volume: number) { const audioManager = AudioManager.getInstance(); if (audioManager) { audioManager.setAllSoundVolume(volume); } //console.log(`[SoundController] 设置音效音量: ${volume}`); } /** * 应用音乐音量到音频系统 */ private applyMusicVolume(volume: number) { const audioManager = AudioManager.getInstance(); if (audioManager) { audioManager.setMusicVolume(volume); } //console.log(`[SoundController] 设置音乐音量: ${volume}`); } /** * 保存设置到本地存储 */ private saveSettings() { const settings = { soundEffectEnabled: this.soundEffectEnabled, musicEnabled: this.musicEnabled, soundEffectVolume: this.savedSoundEffectVolume, musicVolume: this.savedMusicVolume }; // 兼容已有的本地键(微信端也可用) localStorage.setItem('audioSettings', JSON.stringify(settings)); // 写入到 SaveDataManager 的玩家设置,保证随存档持久化 const sdm = SaveDataManager.getInstance(); if (sdm && typeof sdm.updateSetting === 'function') { sdm.updateSetting('soundEnabled', this.soundEffectEnabled); sdm.updateSetting('musicEnabled', this.musicEnabled); sdm.updateSetting('soundVolume', this.savedSoundEffectVolume); sdm.updateSetting('musicVolume', this.savedMusicVolume); // 设置变更需要立即强制保存,避免5秒节流导致未写盘 if (typeof sdm.savePlayerData === 'function') { sdm.savePlayerData(true); } } } /** * 从本地存储加载设置 */ private loadSettings() { const sdm = SaveDataManager.getInstance(); let loadedFromSDM = false; if (sdm && typeof sdm.getSetting === 'function' && sdm.getPlayerData()) { try { this.soundEffectEnabled = sdm.getSetting('soundEnabled') ?? true; this.musicEnabled = sdm.getSetting('musicEnabled') ?? true; this.savedSoundEffectVolume = sdm.getSetting('soundVolume') ?? 0.8; this.savedMusicVolume = sdm.getSetting('musicVolume') ?? 0.6; loadedFromSDM = true; } catch (e) { // 读取失败则走本地兜底 } } if (!loadedFromSDM) { const savedSettings = localStorage.getItem('audioSettings'); if (savedSettings) { try { const settings = JSON.parse(savedSettings); this.soundEffectEnabled = settings.soundEffectEnabled ?? true; this.musicEnabled = settings.musicEnabled ?? true; this.savedSoundEffectVolume = settings.soundEffectVolume ?? 0.8; this.savedMusicVolume = settings.musicVolume ?? 0.6; } catch (e) { console.warn('[SoundController] 加载音频设置失败:', e); } } } // 从SaveDataManager加载震动设置 if (sdm) { this.vibrationEnabled = sdm.getSetting('vibrationEnabled'); } // 更新UI显示 this.updateUI(); } /** * 更新UI显示 */ private updateUI() { // 更新勾选标记 if (this.soundEffectCheck) { this.soundEffectCheck.active = this.soundEffectEnabled; } if (this.musicCheck) { this.musicCheck.active = this.musicEnabled; } // 更新滑动条和进度条 if (this.soundEffectSlider) { this.soundEffectSlider.progress = this.soundEffectEnabled ? this.savedSoundEffectVolume : 0; this.updateProgressBar(this.soundEffectProgressBar, this.soundEffectSlider.progress); // 应用当前滑条音量到音频系统(初始化时也生效) this.applySoundEffectVolume(this.soundEffectSlider.progress); } if (this.musicSlider) { this.musicSlider.progress = this.musicEnabled ? this.savedMusicVolume : 0; this.updateProgressBar(this.musicProgressBar, this.musicSlider.progress); // 应用当前滑条音量到音频系统(初始化时也生效) this.applyMusicVolume(this.musicSlider.progress); } // 更新震动滑动按钮位置(不使用动画,直接设置位置) this.updateVibrationSlideButtonImmediate(); } /** * 获取当前音效音量 */ public getSoundEffectVolume(): number { return this.soundEffectEnabled ? this.savedSoundEffectVolume : 0; } /** * 获取当前音乐音量 */ public getMusicVolume(): number { return this.musicEnabled ? this.savedMusicVolume : 0; } /** * 设置音效音量 */ public setSoundEffectVolume(volume: number) { this.savedSoundEffectVolume = Math.max(0, Math.min(1, volume)); if (this.soundEffectEnabled && this.soundEffectSlider) { this.soundEffectSlider.progress = this.savedSoundEffectVolume; this.updateProgressBar(this.soundEffectProgressBar, this.savedSoundEffectVolume); this.applySoundEffectVolume(this.savedSoundEffectVolume); } this.saveSettings(); } /** * 设置音乐音量 */ public setMusicVolume(volume: number) { this.savedMusicVolume = Math.max(0, Math.min(1, volume)); if (this.musicEnabled && this.musicSlider) { this.musicSlider.progress = this.savedMusicVolume; this.updateProgressBar(this.musicProgressBar, this.savedMusicVolume); this.applyMusicVolume(this.savedMusicVolume); } this.saveSettings(); } /** * 获取当前震动状态 */ public getVibrationEnabled(): boolean { return this.vibrationEnabled; } /** * 设置震动状态 */ public setVibrationEnabled(enabled: boolean) { this.vibrationEnabled = enabled; this.updateVibrationSlideButton(); this.saveVibrationSetting(); } /** * 开启音效和音乐 */ private enableSoundEffectAndMusic() { // 如果音效未开启,则开启音效 if (!this.soundEffectEnabled) { this.soundEffectEnabled = true; // 恢复之前保存的音量或使用默认值0.5 const volumeToRestore = this.savedSoundEffectVolume > 0 ? this.savedSoundEffectVolume : 0.5; this.soundEffectSlider.progress = volumeToRestore; this.updateProgressBar(this.soundEffectProgressBar, volumeToRestore); this.applySoundEffectVolume(volumeToRestore); // 更新勾选标记显示 if (this.soundEffectCheck) { this.soundEffectCheck.active = true; } } // 如果音乐未开启,则开启音乐 if (!this.musicEnabled) { this.musicEnabled = true; // 恢复之前保存的音量或使用默认值0.5 const volumeToRestore = this.savedMusicVolume > 0 ? this.savedMusicVolume : 0.5; this.musicSlider.progress = volumeToRestore; this.updateProgressBar(this.musicProgressBar, volumeToRestore); this.applyMusicVolume(volumeToRestore); // 更新勾选标记显示 if (this.musicCheck) { this.musicCheck.active = true; } } this.saveSettings(); } /** * 关闭音效和音乐 */ private disableSoundEffectAndMusic() { // 关闭音效 if (this.soundEffectEnabled) { this.soundEffectEnabled = false; // 保存当前音量并设置为0 this.savedSoundEffectVolume = this.soundEffectSlider.progress; this.soundEffectSlider.progress = 0; this.updateProgressBar(this.soundEffectProgressBar, 0); this.applySoundEffectVolume(0); // 更新勾选标记显示 if (this.soundEffectCheck) { this.soundEffectCheck.active = false; } } // 关闭音乐 if (this.musicEnabled) { this.musicEnabled = false; // 保存当前音量并设置为0 this.savedMusicVolume = this.musicSlider.progress; this.musicSlider.progress = 0; this.updateProgressBar(this.musicProgressBar, 0); this.applyMusicVolume(0); // 更新勾选标记显示 if (this.musicCheck) { this.musicCheck.active = false; } } this.saveSettings(); } }