UNPKG

aitetris

Version:

致敬程序员阿列克谢·帕基特诺夫带给全世界人民的欢乐摸鱼时光,今天我们与AI一起重制了这款经典摸鱼小游戏,公益、免费、开源、分享给大家~ In tribute to programmer Alexey Pajitnov, who brought joy and countless delightful slacking-off moments to people around the world, we've teamed up with AI to remake the classic time-kill

878 lines (763 loc) 36.5 kB
const SoundManager_7ree = { bgmTracks: [], soundEffects: {}, // 添加音效映射对象 currentBgm: null, currentBgmIndex: 0, // 添加当前播放的BGM索引 isMuted: false, soundButton: null, audioUnlocked: false, firstTouch: true, // 记录第一次点击 audioContext: null, // AudioContext 实例 welcomeCard: null, // 欢迎卡片引用 welcomeStartButton: null, // 欢迎页面开始按钮引用 isInitialized: false, _bgmPlaybackIntentionallyStopped: false, // 新增:标记BGM是否被故意停止 bgmPath: '', sfxPath: '', volume: 0.5, init: function() { console.log(getText_7ree('logSoundManagerInitStart')); this.isInitialized = true; // 先获取DOM元素引用 this.welcomeCard = document.getElementById('welcome_card_7ree'); this.welcomeStartButton = document.getElementById('welcome_start_btn_7ree'); this.soundButton = document.getElementById('sound_btn_7ree'); // 检查配置是否存在 const hasConfig = (typeof config !== 'undefined' && typeof config.audio !== 'undefined'); const configDefaultOn = hasConfig ? config.audio.defaultOn : true; console.log(getText_7ree('logSMConfigDefaultSound') + (hasConfig ? (configDefaultOn ? getText_7ree('enabled') : getText_7ree('disabled')) : "Default:" + getText_7ree('enabled'))); // 获取本地存储的静音状态 const hasSavedMutedState = localStorage.getItem('tetris_muted_7ree') !== null; const savedMutedState = localStorage.getItem('tetris_muted_7ree'); // 如果本地存储中有值且不是首次运行,使用本地存储的值 if (hasSavedMutedState) { this.isMuted = savedMutedState === 'true'; console.log(getText_7ree('logSMLoadMuteLocal') + this.isMuted); } else { // 否则使用配置中的默认值 this.isMuted = !configDefaultOn; console.log(getText_7ree('logSMUseConfigDefaultMute') + this.isMuted + getText_7ree('logSMConfigDefaultOn', {defaultOn: configDefaultOn})); // 保存到本地存储 localStorage.setItem('tetris_muted_7ree', this.isMuted); localStorage.setItem('tetris_sound_on_7ree', !this.isMuted); } // 同步声音状态到游戏实例(如果游戏实例已初始化) if (window.tetrisGame_7ree) { // 如果游戏实例已存在,确保声音状态一致 if (window.tetrisGame_7ree.isSoundOn !== !this.isMuted) { console.log(getText_7ree('logSMSyncGameInstance') + this.isMuted); window.tetrisGame_7ree.isSoundOn = !this.isMuted; // 保存到本地存储 localStorage.setItem('tetris_sound_on_7ree', window.tetrisGame_7ree.isSoundOn); // 更新UI if (window.tetrisGame_7ree.soundButton) { window.tetrisGame_7ree.soundButton.textContent = window.tetrisGame_7ree.isSoundOn ? '🔊' : '🔇'; } } } // 初始化音效和BGM路径 this.loadSoundEffectsFromConfig(); this.loadBgmFromConfig(); // 创建音频上下文 this.createAudioContext(); // 设置欢迎界面的事件监听 this.setupWelcomeEvents(); // 初始化按钮图标 this.updateButtonIcon(); console.log(getText_7ree('logSMInitComplete') + this.isMuted); }, // 从配置文件加载音效名称映射 loadSoundEffectsFromConfig: function() { // 默认音效映射 this.soundEffects = { move: 'se_Move', rotate: 'se_Rotate', drop: 'se_Drop', lineClear: 'se_LineClear', combo: 'se_Combo', tSpin: 'se_TSpin', mini: 'se_Mini', gameOver: 'se_GameOver', levelUp: 'se_LevelUp', pause: 'se_Pause', resume: 'se_Resume' }; // 检查配置文件中是否有音效定义 if (typeof config !== 'undefined' && config.audio && config.audio.files && config.audio.files.soundEffects) { // 使用配置文件中的音效定义 this.soundEffects = config.audio.files.soundEffects; console.log(getText_7ree('logSoundEffectsLoaded')); } else { console.warn(getText_7ree('warnSoundEffectsNotFound')); } }, // 获取音效文件路径 getSoundEffectPath: function(effectKey) { if (!this.soundEffects || !this.soundEffects[effectKey]) { console.warn(getText_7ree('warnSFXPathNotFound', { effectKey: effectKey })); return ''; } // 获取音频基础路径(带有结尾斜杠) const audioPath = (typeof config !== 'undefined' && config.audio && config.audio.path) ? ((config.audio.path.endsWith('/')) ? config.audio.path : config.audio.path + '/') : 'resource/sounds/'; return `${audioPath}${this.soundEffects[effectKey]}_7ree.mp3`; }, // 从配置文件加载BGM列表 loadBgmFromConfig: function() { this.bgmTracks = []; // 检查配置是否存在 if (typeof config === 'undefined' || !config.audio || !config.audio.files || !config.audio.files.bgMusic || !Array.isArray(config.audio.files.bgMusic) || config.audio.files.bgMusic.length === 0) { console.warn(getText_7ree('warnBGMListNotFound')); // 使用默认BGM(硬编码的后备选项) this.bgmTracks = ['resource/sounds/bgm_1_7ree.mp3']; return; } // 获取音频基础路径(带有结尾斜杠) const audioPath = (config.audio.path || 'resource/sounds/').endsWith('/') ? config.audio.path : config.audio.path + '/'; // 构建完整的BGM路径列表 config.audio.files.bgMusic.forEach(bgm => { // 检查bgm是否已经包含后缀 let fileName = bgm; if (!fileName.endsWith('.mp3')) { fileName += '_7ree.mp3'; } this.bgmTracks.push(`${audioPath}${fileName}`); }); // 随机打乱BGM顺序,增加播放随机性 this.shuffleBgmTracks(); console.log(getText_7ree('logBGMLoaded'), this.bgmTracks); }, // 随机打乱BGM列表顺序 shuffleBgmTracks: function() { for (let i = this.bgmTracks.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [this.bgmTracks[i], this.bgmTracks[j]] = [this.bgmTracks[j], this.bgmTracks[i]]; } this.currentBgmIndex = 0; // 重置索引 }, // 创建AudioContext createAudioContext: function() { if (!this.audioContext) { try { window.AudioContext = window.AudioContext || window.webkitAudioContext; this.audioContext = new AudioContext(); console.log(getText_7ree('logAudioContextCreated')); } catch (e) { console.error(getText_7ree('errorAudioContextCreateFail'), e); } } return this.audioContext; }, // 设置欢迎页面事件处理 setupWelcomeEvents: function() { if (!this.welcomeStartButton || !this.welcomeCard) { console.error(getText_7ree('errorWelcomeElementsNotFound')); return; } // 监听欢迎页面的开始按钮点击 if (DeviceHandler_7ree && DeviceHandler_7ree.isMobile()) { // 在移动设备上使用 touchstart 事件 this.welcomeStartButton.addEventListener('touchstart', (e) => { e.preventDefault(); // 创建AudioContext(如果尚未创建) this.createAudioContext(); // 在用户交互中解锁音频上下文 this.unlockAudioContext(); // 创建并播放一个短暂的空声音以解锁音频 this.playEmptySoundForUnlock(); // 增加延迟时间,确保移动设备上有足够时间解锁音频 setTimeout(() => this.handleGameStart(), 500); }); } else { // PC 上使用 click 事件 this.welcomeStartButton.addEventListener('click', () => { // 确保AudioContext已创建 this.createAudioContext(); this.handleGameStart(); }); } }, // 播放空声音解锁音频 playEmptySoundForUnlock: function() { try { // 创建一个短暂的空声音 const audio = new Audio(); audio.play().catch(e => console.warn(getText_7ree('warnEmptySoundPlayFail'), e)); // 同时尝试使用 AudioContext if (this.audioContext) { const buffer = this.audioContext.createBuffer(1, 1, 22050); const source = this.audioContext.createBufferSource(); source.buffer = buffer; source.connect(this.audioContext.destination); source.start(0); this.audioUnlocked = true; console.log(getText_7ree('logEmptyBufferPlayed')); } } catch (e) { console.warn(getText_7ree('warnEmptySoundUnlockFail'), e); } }, // 处理游戏开始逻辑 handleGameStart: function() { console.log(getText_7ree('logGameStartUnlockAudio')); // 解锁音频上下文 this.unlockAudioContext(); // 确保静音状态与游戏实例同步 if (window.tetrisGame_7ree) { // 如果游戏实例存在,确保声音状态一致 if (window.tetrisGame_7ree.isSoundOn !== !this.isMuted) { console.log(getText_7ree('logGameStartSyncSound') + this.isMuted); window.tetrisGame_7ree.isSoundOn = !this.isMuted; // 更新游戏实例UI if (window.tetrisGame_7ree.soundButton) { window.tetrisGame_7ree.soundButton.textContent = window.tetrisGame_7ree.isSoundOn ? '🔊' : '🔇'; } } } // 隐藏欢迎卡片 if (this.welcomeCard) { this.welcomeCard.classList.add('card_hidden'); // 一秒后完全移除欢迎卡片(为了动画效果) setTimeout(() => { this.welcomeCard.style.display = 'none'; // 在欢迎卡片隐藏后触发游戏开始 if (window.tetrisGame_7ree) { // 调用游戏开始方法,传递true表示从声音管理器调用 window.tetrisGame_7ree.startGame(true); // 延迟一段时间后再播放BGM,确保游戏状态已更新 setTimeout(() => { // 开始播放背景音乐(仅当非静音状态) if (!this.isMuted && window.tetrisGame_7ree.isPlaying) { console.log(getText_7ree('logGameStartTryPlayBGM')); // 停止可能已存在的BGM if (this.currentBgm) { console.log(getText_7ree('logGameStartStopCurrentBGM')); this.stopBgm(); } // 使用创建新 Audio 元素的方式播放 this.playBgmWithNewAudio(); } else { console.log(getText_7ree('logGameStartMutedNoBGM')); } }, 300); } else { console.error(getText_7ree('errorGameInstanceNotFound')); } }, 500); } else { console.log(getText_7ree('logGameStartWelcomeNotFound')); // 如果找不到欢迎卡片,直接开始游戏 if (window.tetrisGame_7ree) { window.tetrisGame_7ree.startGame(true); // 同样需要延迟BGM播放 setTimeout(() => { if (!this.isMuted && window.tetrisGame_7ree.isPlaying) { this.playBgmWithNewAudio(); } }, 300); } else { console.error(getText_7ree('errorGameInstanceNotFound')); } } }, // 使用新 Audio 元素方式播放 BGM(避免 fetch) playBgmWithNewAudio: function() { try { // 如果已经有BGM或处于静音状态,则不进行操作 if (this.isMuted) { console.log(getText_7ree('logPlayBGMNotMuted')); return; } if (this.currentBgm && typeof this.currentBgm.paused !== 'undefined' && !this.currentBgm.paused) { console.log(getText_7ree('logPlayBGMPlaying')); return; } if (this.bgmTracks.length === 0) { console.log(getText_7ree('logPlayBGMNoTracks')); return; } // 如果已有 Audio 对象但是处于暂停状态,则尝试恢复播放 if (this.currentBgm && typeof this.currentBgm.play === 'function' && this.currentBgm.paused) { console.log(getText_7ree('logPlayBGMResume')); try { const playPromise = this.currentBgm.play(); if (playPromise !== undefined) { playPromise.then(() => { console.log(getText_7ree('logPlayBGMResumeSuccess')); }).catch(error => { console.error(getText_7ree('logPlayBGMResumeFail'), error); // 出错时重新创建 this.currentBgm = null; this.createAndPlayNewBgm(); }); } return; } catch (e) { console.error(getText_7ree('logPlayBGMResumeError'), e); this.currentBgm = null; } } // 创建新的BGM this.createAndPlayNewBgm(); } catch (e) { console.error(getText_7ree('errorPlayBGMGeneric'), e); this.currentBgm = null; } }, // 创建并播放新的BGM createAndPlayNewBgm: function() { console.log(getText_7ree('logPlayBGMCreateNew')); // 重置故意停止标志 this._bgmPlaybackIntentionallyStopped = false; // 如果游戏已结束或处于静音状态,则不创建新BGM if (this.isMuted) { console.log(getText_7ree('logPlayBGMNotMuted')); return; } // 修改游戏状态检查逻辑,避免过早判断游戏状态 if (window.tetrisGame_7ree && window.tetrisGame_7ree.isPlaying === false && window.tetrisGame_7ree.gameEnded === true) { console.log(getText_7ree('logPlayBGMGameEnded')); return; } try { // 使用当前索引选择BGM,而不是随机选择 if (this.currentBgmIndex >= this.bgmTracks.length) { this.currentBgmIndex = 0; // 循环播放 } const trackSrc = this.bgmTracks[this.currentBgmIndex]; console.log(getText_7ree('logPlayBGMTrackInfo', { index: this.currentBgmIndex + 1, total: this.bgmTracks.length, src: trackSrc })); // 使用普通的 Audio 元素播放 const audio = new Audio(trackSrc); audio.loop = false; // 不循环单曲,改为播放完后切换到下一首 audio.volume = 0.3; // 记录BGM元素,即使播放尚未开始 this.currentBgm = audio; // 添加播放结束事件处理,切换到下一首 audio.addEventListener('ended', () => { console.log(getText_7ree('logPlayBGMEndedNext')); this.playNextBgm(); }); // 播放前添加事件监听 audio.addEventListener('canplaythrough', () => { console.log(getText_7ree('logPlayBGMLoadedTryPlay')); // 检查是否已被故意停止 if (this._bgmPlaybackIntentionallyStopped) { console.log(getText_7ree('logPlayBGMStoppedCancel')); return; } // 再次检查游戏状态和静音状态 if (this.isMuted || (window.tetrisGame_7ree && window.tetrisGame_7ree.isPlaying === false && window.tetrisGame_7ree.gameEnded === true)) { console.log(getText_7ree('logPlayBGMNotMuted')); return; } // 尝试播放 if (audio) { const playPromise = audio.play(); if (playPromise !== undefined) { playPromise.then(() => { console.log(getText_7ree('logPlayBGMSuccess')); }).catch(error => { console.error(getText_7ree('errorPlayBGMFail'), error); // 移动端可能需要等待用户下一次交互 this.setupBgmPlayOnNextInteraction(audio); }); } } }); audio.addEventListener('error', (e) => { console.error(getText_7ree('errorPlayBGMLoad'), e); this.currentBgm = null; // 出现错误时尝试播放下一首 setTimeout(() => this.playNextBgm(), 1000); }); // 加载音频 audio.load(); } catch (e) { console.error(getText_7ree('errorPlayBGMGeneric'), e); this.currentBgm = null; // 发生异常时尝试播放下一首 setTimeout(() => this.playNextBgm(), 1000); } }, // 播放下一首BGM playNextBgm: function() { // 如果已静音或游戏已结束,不继续播放 if (this.isMuted || (window.tetrisGame_7ree && (window.tetrisGame_7ree.isPlaying === false || window.tetrisGame_7ree.gameEnded === true || window.tetrisGame_7ree.isPaused === true))) { console.log("[Sound] 已静音或游戏未运行,不播放下一首BGM"); return; } // 切换到下一首 this.currentBgmIndex++; if (this.currentBgmIndex >= this.bgmTracks.length) { console.log(getText_7ree('logBGMShuffled')); this.shuffleBgmTracks(); // 播放完所有曲目后重新洗牌 } // 停止当前BGM if (this.currentBgm) { this.stopBgm(); } // 延迟一会儿再播放下一首,避免立即切换 setTimeout(() => { console.log(getText_7ree('logPlayBGMPlayNext')); this.createAndPlayNewBgm(); }, 500); }, // 设置在下一次用户交互时播放 BGM setupBgmPlayOnNextInteraction: function(audioElement) { console.log(getText_7ree('logPlayBGMInteractionSetup')); // 保存音频元素引用,以便后续播放 const audio = audioElement || (this.currentBgm && typeof this.currentBgm.play === 'function' ? this.currentBgm : null); if (!audio) { console.error(getText_7ree('errorPlayBGMNoElement')); return; } // 监听文档上的点击或触摸事件 const playOnInteraction = (e) => { if (!this.isMuted && !(window.tetrisGame_7ree && !window.tetrisGame_7ree.isPlaying)) { // 确保用户交互中解锁音频 this.unlockAudioContext(); try { const playPromise = audio.play(); playPromise.then(() => { console.log(getText_7ree('logPlayBGMInteractionSuccess')); // 确保设置 currentBgm this.currentBgm = audio; }).catch(e => { console.error(getText_7ree('errorPlayBGMInteractionFail'), e); }); } catch (e) { console.error(getText_7ree('errorPlayBGMGeneric'), e); } } else { console.log("[Sound] 已静音或游戏已结束,不播放BGM"); } // 移除事件监听 document.removeEventListener('click', playOnInteraction); document.removeEventListener('touchstart', playOnInteraction); }; document.addEventListener('click', playOnInteraction); document.addEventListener('touchstart', playOnInteraction); }, // 解锁 AudioContext unlockAudioContext: function() { if (this.audioUnlocked || !this.audioContext) return; if (this.audioContext.state === 'suspended') { console.log(getText_7ree('logAudioContextTryResume')); this.audioContext.resume().then(() => { console.log(getText_7ree('logAudioContextResumed')); this.audioUnlocked = true; }).catch(e => { console.error(getText_7ree('errorAudioContextResumeFail'), e); }); } else { console.log(getText_7ree('logAudioContextState') + this.audioContext.state); if (this.audioContext.state === 'running') { this.audioUnlocked = true; } } // 创建一个空的音频缓冲区并播放,这也可以帮助解锁 if (!this.audioUnlocked && this.audioContext) { try { console.log(getText_7ree('logAudioContextEmptyBuffer')); const buffer = this.audioContext.createBuffer(1, 1, 22050); const source = this.audioContext.createBufferSource(); source.buffer = buffer; source.connect(this.audioContext.destination); source.start(0); this.audioUnlocked = true; console.log(getText_7ree('logAudioContextEmptyBufferSuccess')); } catch (e) { console.warn(getText_7ree('warnAudioContextEmptyBufferFail'), e); } } }, // 直接播放背景音乐 playBgmDirect: function() { if (!this.audioContext) { console.error(getText_7ree('errorAudioContextNotInit')); return; } if (this.isMuted) return; if (!this.bgmTracks || this.bgmTracks.length === 0) { console.error(getText_7ree('errorBGMListEmpty')); return; } // 如果当前没有BGM或播放结束,选择下一首 if (!this.currentBgm || this.currentBgm.ended || this.currentBgm.paused) { this.currentBgmIndex = (this.currentBgmIndex + 1) % this.bgmTracks.length; const bgmName = this.bgmTracks[this.currentBgmIndex]; const bgmSrc = `${this.bgmPath}${bgmName}`; console.log(getText_7ree('logTryLoadBGM', { bgmName: bgmName })); if (!this.currentBgm) { this.currentBgm = new Audio(); this.currentBgm.loop = false; this.currentBgm.volume = this.volume; this.currentBgm.onended = () => { console.log(getText_7ree('logBGMEndedNext')); this.playBgmDirect(); // 自动播放下一首 }; } this.currentBgm.src = bgmSrc; this.currentBgm.load(); // 加载完成后尝试播放 this.currentBgm.oncanplaythrough = () => { if (this.isMuted) return; // 再次检查静音状态 const playPromise = this.currentBgm.play(); if (playPromise !== undefined) { playPromise.then(_ => { console.log(getText_7ree('logStartPlayBGM', { src: bgmSrc })); }).catch(error => { console.error(getText_7ree('errorPlayBGM', { error: error })); }); } }; this.currentBgm.onerror = (e) => { console.error(getText_7ree('errorLoadBGM', { bgmName: bgmName, error: e })); }; } // 如果当前BGM已加载但暂停,则继续播放 else if (this.currentBgm && this.currentBgm.paused) { if (this.isMuted) return; // 再次检查静音状态 const playPromise = this.currentBgm.play(); if (playPromise !== undefined) { playPromise.catch(error => { console.error(getText_7ree('errorPlayBGM', { error: error })); }); } } }, // 直接切换静音状态 toggleMute: function() { this.isMuted = !this.isMuted; localStorage.setItem('tetris_muted_7ree', this.isMuted); console.log(getText_7ree('logToggleMute', { mutedState: (this.isMuted ? getText_7ree('muted') : getText_7ree('unmuted')) })); if (this.isMuted) { this.stopBgm(); // 静音时停止BGM // 无需停止音效,因为播放前会检查 isMuted } else { // 如果之前有BGM在播放(但被暂停了),尝试恢复 // 注意:如果之前没有BGM在播放,则不自动开始 this.resumeSuspendedContext(); // 确保上下文活跃 // 如果游戏正在进行中,恢复BGM if (window.tetrisGame_7ree && window.tetrisGame_7ree.isPlaying && !window.tetrisGame_7ree.isPaused) { this.playBgmDirect(); } } this.updateButtonIcon(); // 同步游戏实例的状态 if (window.tetrisGame_7ree) { const gameShouldBeSoundOn = !this.isMuted; if (window.tetrisGame_7ree.isSoundOn !== gameShouldBeSoundOn) { window.tetrisGame_7ree.isSoundOn = gameShouldBeSoundOn; localStorage.setItem('tetris_sound_on_7ree', gameShouldBeSoundOn); } } }, // 增强的停止BGM方法 stopBgm: function() { console.log(getText_7ree('logStopBGMStart')); if (this.currentBgm) { console.log(getText_7ree('logStopBGMFound') + (typeof this.currentBgm) + ", 实例: " + (this.currentBgm instanceof HTMLAudioElement ? getText_7ree('htmlElement') : getText_7ree('other'))); // 设置故意停止标志 this._bgmPlaybackIntentionallyStopped = true; console.log(getText_7ree('logStopBGMSetFlag')); try { // 先移除事件监听器,防止异步事件后续触发播放 if (this.currentBgm instanceof HTMLAudioElement) { console.log(getText_7ree('logStopBGMRemoveListeners')); this.currentBgm.oncanplaythrough = null; this.currentBgm.onloadeddata = null; this.currentBgm.onplaying = null; this.currentBgm.onerror = null; this.currentBgm.onended = null; } // 检测是音频元素还是AudioBuffer if (this.currentBgm instanceof HTMLAudioElement) { console.log(getText_7ree('logStopBGMTryStopHTML')); this.currentBgm.pause(); this.currentBgm.currentTime = 0; console.log(getText_7ree('logStopBGMHTMLStopped')); } else if (this.currentBgm.stop && typeof this.currentBgm.stop === 'function') { console.log(getText_7ree('logStopBGMTryStopContext')); this.currentBgm.stop(0); console.log(getText_7ree('logStopBGMContextStopped')); } else { console.warn(getText_7ree('warnStopBGMUnknownType')); if (typeof this.currentBgm.pause === 'function') { this.currentBgm.pause(); console.log("[Sound] 通用 pause() 已调用"); } else { console.warn(getText_7ree('warnStopBGMPauseNotFound')); } } // 记录更多信息并确保清除引用 console.log(getText_7ree('logStopBGMCleared')); this.currentBgm = null; } catch (e) { console.error(getText_7ree('errorStopBGM'), e); // 强制清除引用,防止出错后无法继续播放新音乐 this.currentBgm = null; } } else { console.log(getText_7ree('logStopBGMNotFound')); // 即使没有 BGM,也标记为故意停止,防止旧的异步事件触发 this._bgmPlaybackIntentionallyStopped = true; console.log(getText_7ree('logStopBGMSetFlagNoBGM')); } console.log(getText_7ree('logStopBGMEnd')); }, // 以下为向后兼容的方法 unlockAudio: function() { this.createAudioContext(); this.unlockAudioContext(); return Promise.resolve(this.audioUnlocked); }, playBgm: function() { if (this.isMuted) { return Promise.resolve(); } // 调用新方法 this.createAudioContext(); this.unlockAudioContext(); this.playBgmWithNewAudio(); return Promise.resolve(); }, updateButtonIcon: function() { if (this.soundButton) { this.soundButton.textContent = this.isMuted ? '🔇' : '🔊'; } }, playBgmOnGameStart: function() { console.log(getText_7ree('logGameStartUnlockAudio')); // 检查静音状态 if (this.isMuted) { console.log(getText_7ree('logGameStartMutedNoBGM')); return Promise.resolve(); } // 确保音频上下文已创建并解锁 this.createAudioContext(); this.unlockAudioContext(); // 停止现有BGM(如果有) if (this.currentBgm) { console.log(getText_7ree('logGameStartStopCurrentBGM')); this.stopBgm(); } // 使用延迟确保音频上下文就绪 setTimeout(() => { if (!this.isMuted && !this.currentBgm) { console.log(getText_7ree('logGameStartDelayPlayBGM')); this.playBgmWithNewAudio(); } }, 100); return Promise.resolve(); }, // 修复:确保音频上下文在需要时被创建 ensureAudioContext: function() { return this.createAudioContext(); }, resumeSuspendedContext() { if (this.audioContext && this.audioContext.state === 'suspended') { this.audioContext.resume().then(() => { console.log(getText_7ree('logAudioContextResumed')); }).catch(e => console.error(getText_7ree('errorResumeAudioContext', { error: e }))); } }, setupAutoResume() { if (!this.audioContext) return; if (this.audioContext.state === 'suspended') { console.warn(getText_7ree('warnAudioContextSuspended')); const resumeHandler = () => { this.resumeSuspendedContext(); document.body.removeEventListener('click', resumeHandler, true); document.body.removeEventListener('touchstart', resumeHandler, true); document.body.removeEventListener('keydown', resumeHandler, true); }; document.body.addEventListener('click', resumeHandler, { once: true, capture: true }); document.body.addEventListener('touchstart', resumeHandler, { once: true, capture: true }); document.body.addEventListener('keydown', resumeHandler, { once: true, capture: true }); } }, setVolume(volumeLevel) { this.volume = Math.max(0, Math.min(1, volumeLevel)); console.log(getText_7ree('logSetVolume', { volume: this.volume })); if (this.currentBgm) { this.currentBgm.volume = this.volume; } // 更新所有音效的音量 for (const effectName in this.soundEffects) { if (this.soundEffects[effectName]) { this.soundEffects[effectName].volume = this.volume; } } }, loadSoundEffect(effectName, fileName) { const filePath = `${this.sfxPath}${fileName}_7ree.mp3`; console.log(getText_7ree('logTryLoadSFX', { effectName: effectName })); const audio = new Audio(filePath); audio.preload = 'auto'; audio.volume = this.volume; // 不自动播放,仅加载 audio.load(); audio.onerror = (e) => { console.error(getText_7ree('errorLoadSFX', { effectName: effectName, error: e })); }; this.soundEffects[effectName] = audio; }, playSoundEffect(name) { if (this.isMuted) return; const sound = this.soundEffects[name]; if (sound) { if (sound.readyState >= 2) { // HAVE_CURRENT_DATA or more sound.currentTime = 0; const playPromise = sound.play(); if (playPromise !== undefined) { playPromise.then(_ => { // console.log(`播放音效: ${name}`); }).catch(error => { console.error(getText_7ree('errorPlaySFX', { name: name, error: error })); }); } } else { // 如果音频未加载完成,尝试在 canplaythrough 事件中播放 console.warn(getText_7ree('logPlaySFXWarnNotReady')); // 可以添加一个临时监听器来播放,但不推荐,可能导致延迟 // sound.addEventListener('canplaythrough', () => sound.play(), { once: true }); } } else { console.warn(getText_7ree('warnSFXNotFoundOrLoaded', { name: name })); } }, }; // 如果页面已加载完成,则初始化 if (document.readyState === 'complete' || document.readyState === 'interactive') { // 页面已加载,延迟初始化以确保其他脚本已就绪 setTimeout(() => { if (!SoundManager_7ree.isInitialized) { console.log(getText_7ree('logSMDelayedInit')); SoundManager_7ree.init(); } }, 300); // 增加延迟时间 } else { // 监听DOM加载完成事件 document.addEventListener('DOMContentLoaded', () => { // 延迟初始化,以确保游戏实例已创建 setTimeout(() => { if (!SoundManager_7ree.isInitialized) { console.log(getText_7ree('logSMDOMContentLoadedInit')); SoundManager_7ree.init(); } }, 300); // 增加延迟时间 }); }