// 主游戏类 class MagicPotGame { constructor() { this.canvas = document.getElementById('gameCanvas'); this.ctx = this.canvas.getContext('2d'); this.gameState = 'idle'; // idle, activated, cooking, overflowing, stopped this.currentFood = null; this.foodCount = 0; // this.particles = []; // 不再需要单独的粒子数组,使用particleSystem管理 this.lastTime = 0; // 游戏配置 this.config = { maxFoodCount: 100, // 最大食物计数 maxParticles: 150, // 最大粒子数量 maxAnimals: 8, // 最大动物数量 animalSpawnThreshold: 5, // 动物出现阈值(降低到5以便更快测试) easterEggThreshold: 30, // 彩蛋触发阈值 particleSpawnRate: 1, // 粒子生成速率(调整为1,降低食物生成速度) cookingDuration: 3000, // 3秒烹饪时间 cleanupInterval: 5000, // 清理间隔(毫秒) maxGroundedParticles: 80 // 地面最大粒子数 }; // 初始化组件 this.voice = new VoiceRecognition(); this.keyboard = new KeyboardInputHandler(); this.pot = new MagicPot(this.canvas.width / 2, this.canvas.height / 2 + 50); this.particleSystem = new ParticleSystem(); this.animalSystem = new AnimalSystem(this.canvas); // 传入Canvas引用 this.textToImage = new TextToImageAPI(); this.audio = window.audioManager; // 食物生成控制 this.lastFoodSpawnTime = 0; this.foodSpawnInterval = 500; // 每500毫秒生成一次食物(显著降低生成速度) // 性能监控 this.lastCleanupTime = 0; this.performanceStats = { particles: 0, animals: 0, fps: 0, lastFpsTime: 0, frameCount: 0 }; this.init(); } init() { this.setupEventListeners(); this.setupCanvas(); this.gameLoop(); this.updateUI(); // 显示初始提示 this.showDebug('游戏初始化完成,等待语音命令...'); // 启动定期清理 this.startPerformanceMonitoring(); } setupEventListeners() { // 语音识别事件 this.voice.onResult = (transcript) => { this.handleVoiceCommand(transcript); }; this.voice.onError = (error) => { this.showDebug(`语音识别错误: ${error}`); }; this.voice.onStatusChange = (status) => { this.updateVoiceStatus(status); }; // 键盘输入事件 this.keyboard.onCommand = (command) => { this.handleKeyboardCommand(command); }; // 键盘调试快捷键 document.addEventListener('keydown', (e) => { if (e.key === 'F12') { this.toggleDebug(); } else if (e.key === 'F11') { this.testAudio(); } else if (e.key === 'F10') { this.toggleAudio(); } else if (e.key === 'F9') { e.preventDefault(); // 确保阻止浏览器默认行为 this.toggleKeyboardActivation(); } else if (e.key === 'F8') { this.toggleKeyboardPanel(); } else if (e.key === 'F7') { this.clearCommandHistory(); } else if (e.key === 'F6') { this.restartVoice(); } else if (e.key === 'F5') { this.resetKeyboardPanelPosition(); } else if (e.key === 'F4') { this.adjustFoodSpawnSpeed(); } else if (e.key === 'a' && e.altKey) { e.preventDefault(); this.forceSpawnAnimal(); } }); // 音效按钮 const audioButton = document.getElementById('audioButton'); if (audioButton) { audioButton.addEventListener('click', () => { this.toggleAudio(); }); this.updateAudioButton(); } // 帮助按钮 const helpButton = document.getElementById('helpButton'); if (helpButton) { helpButton.addEventListener('click', () => { this.showVoiceHelp(); }); } // 窗口大小调整 window.addEventListener('resize', () => { this.resizeCanvas(); }); } setupCanvas() { // 设置高DPI显示 const dpr = window.devicePixelRatio || 1; const rect = this.canvas.getBoundingClientRect(); this.canvas.width = rect.width * dpr; this.canvas.height = rect.height * dpr; this.ctx.scale(dpr, dpr); this.canvas.style.width = rect.width + 'px'; this.canvas.style.height = rect.height + 'px'; } handleVoiceCommand(transcript) { const command = transcript.toLowerCase().trim(); this.showDebug(`语音命令: "${command}"`); this.processCommand(command, '语音'); } handleKeyboardCommand(command) { const normalizedCommand = command.toLowerCase().trim(); this.showDebug(`键盘命令: "${command}"`); this.processCommand(normalizedCommand, '键盘'); } processCommand(command, source) { // 统一的命令处理逻辑 // 激活魔法锅 - 更灵活的匹配 if (this.matchActivationCommand(command)) { this.activatePot(); this.showDebug(`通过${source}激活魔法锅`); return; } // 停止烹饪 - 更灵活的匹配 if (this.matchStopCommand(command)) { this.stopCooking(); this.showDebug(`通过${source}停止烹饪`); return; } // 如果锅已激活,处理食物命令 if (this.gameState === 'activated') { const foodName = this.extractFoodName(command); if (foodName) { this.startCooking(foodName); this.showDebug(`通过${source}开始烹饪: ${foodName}`); } else { this.showDebug(`未识别的食物: "${command}" (来源: ${source})`); } } else { // 如果锅未激活,提示用户先激活 if (this.isValidFoodCommand(command)) { this.showDebug(`请先激活魔法锅再烹饪食物 (来源: ${source})`); this.showSpecialMessage('请先说 "cook cook cook pot" 激活魔法锅'); } } } isValidFoodCommand(command) { // 检查是否是有效的食物命令 const foods = [ 'apple', 'banana', 'orange', 'strawberry', 'watermelon', 'grape', 'pizza', 'burger', 'bread', 'rice', 'noodles', 'cake', 'cookie', 'cheese', 'fish', 'chicken', 'carrot', 'tomato', 'corn', 'broccoli', 'potato', 'onion' ]; return foods.some(food => command.includes(food)); } matchActivationCommand(command) { // 多种激活命令的匹配模式 const patterns = [ /cook.*cook.*cook.*pot/, /cook.*pot.*cook.*cook/, /pot.*cook.*cook.*cook/, /cook\s+cook\s+cook\s+pot/, /cook.*three.*times.*pot/, /magic.*pot.*cook/ ]; return patterns.some(pattern => pattern.test(command)); } matchStopCommand(command) { // 多种停止命令的匹配模式 const patterns = [ /stop.*stop.*stop.*pot/, /stop.*pot.*stop.*stop/, /pot.*stop.*stop.*stop/, /stop\s+stop\s+stop\s+pot/, /stop.*three.*times.*pot/, /magic.*pot.*stop/ ]; return patterns.some(pattern => pattern.test(command)); } extractFoodName(command) { // 支持的食物列表 const foods = [ 'apple', 'banana', 'orange', 'strawberry', 'watermelon', 'grape', 'pizza', 'burger', 'bread', 'rice', 'noodles', 'cake', 'cookie', 'cheese', 'fish', 'chicken', 'carrot', 'tomato', 'corn', 'broccoli', 'potato', 'onion' ]; // 在命令中查找食物名称 for (const food of foods) { if (command.includes(food)) { return food; } } // 如果没有找到确切匹配,尝试模糊匹配 for (const food of foods) { if (this.fuzzyMatch(command, food)) { return food; } } return null; } fuzzyMatch(text, target) { // 简单的模糊匹配算法 const threshold = 0.7; const similarity = this.calculateSimilarity(text, target); return similarity >= threshold; } calculateSimilarity(str1, str2) { // 计算两个字符串的相似度 const longer = str1.length > str2.length ? str1 : str2; const shorter = str1.length > str2.length ? str2 : str1; if (longer.length === 0) return 1.0; const distance = this.levenshteinDistance(longer, shorter); return (longer.length - distance) / longer.length; } levenshteinDistance(str1, str2) { // 计算编辑距离 const matrix = []; for (let i = 0; i <= str2.length; i++) { matrix[i] = [i]; } for (let j = 0; j <= str1.length; j++) { matrix[0][j] = j; } for (let i = 1; i <= str2.length; i++) { for (let j = 1; j <= str1.length; j++) { if (str2.charAt(i - 1) === str1.charAt(j - 1)) { matrix[i][j] = matrix[i - 1][j - 1]; } else { matrix[i][j] = Math.min( matrix[i - 1][j - 1] + 1, matrix[i][j - 1] + 1, matrix[i - 1][j] + 1 ); } } } return matrix[str2.length][str1.length]; } activatePot() { if (this.gameState === 'idle') { this.gameState = 'activated'; this.pot.activate(); this.updateUI(); this.showDebug('魔法锅已激活!'); this.showSpecialMessage('🪄 魔法锅已激活!\n现在说出食物名称开始烹饪'); // 播放激活音效 if (this.audio) { this.audio.playPotActivate(); } } } async startCooking(foodName) { if (this.gameState !== 'activated') return; this.gameState = 'cooking'; this.currentFood = foodName; this.pot.startCooking(foodName); this.updateUI(); this.showDebug(`开始烹饪: ${foodName}`); // 播放烹饪音效 if (this.audio) { this.audio.playCooking(); // 烹饪过程中定期播放冒泡声 this.cookingSoundInterval = setInterval(() => { if (this.gameState === 'cooking') { this.audio.playCooking(); } }, 1000); } try { // 生成食物和动物素材 await this.generateAssets(foodName); // 烹饪完成,开始溢出 setTimeout(() => { this.startOverflowing(); }, this.config.cookingDuration); } catch (error) { this.showDebug(`生成素材失败: ${error.message}`); // 即使生成失败也继续游戏 setTimeout(() => { this.startOverflowing(); }, this.config.cookingDuration); } } async generateAssets(foodName) { // 显示生成进度 this.updateCookingProgress(0); // 生成食物图片 this.updateCookingProgress(30); const foodImage = await this.textToImage.generateFood(foodName); // 生成动物图片 this.updateCookingProgress(60); const animalImage = await this.textToImage.generateAnimal(foodName); // 保存生成的素材 this.pot.setFoodAssets(foodImage, animalImage); this.updateCookingProgress(100); this.showDebug(`素材生成完成: ${foodName}`); } startOverflowing() { this.gameState = 'overflowing'; this.pot.startOverflowing(); this.foodCount = 0; // 重置计数器开始计数 this.updateUI(); this.showDebug('食物开始涌出!'); console.log(`开始溢出,食物计数重置为: ${this.foodCount}`); // 停止烹饪音效 if (this.cookingSoundInterval) { clearInterval(this.cookingSoundInterval); this.cookingSoundInterval = null; } } stopCooking() { if (this.gameState === 'overflowing') { this.gameState = 'stopped'; this.pot.stopOverflowing(); this.updateUI(); this.showDebug('停止烹饪'); // 播放停止音效 if (this.audio) { this.audio.playStopCooking(); } // 停止烹饪音效 if (this.cookingSoundInterval) { clearInterval(this.cookingSoundInterval); this.cookingSoundInterval = null; } // 显示统计信息 this.showGameStats(); // 5秒后重置游戏状态 setTimeout(() => { this.resetGame(); }, 5000); } } resetGame() { this.gameState = 'idle'; this.currentFood = null; this.foodCount = 0; this.pot.reset(); this.particleSystem.clear(); this.animalSystem.clear(); this.updateUI(); this.showDebug('游戏已重置,可以重新开始'); } showGameStats() { const stats = { food: this.currentFood, count: this.foodCount, animals: this.animalSystem.getAnimalCount(), particles: this.particleSystem.getParticleCount() }; const message = `本轮统计:\n食物:${stats.food}\n数量:${stats.count}\n动物:${stats.animals}只`; this.showSpecialMessage(message); this.showDebug(`游戏统计: ${JSON.stringify(stats)}`); } gameLoop(currentTime = 0) { const deltaTime = currentTime - this.lastTime; this.lastTime = currentTime; this.update(deltaTime); this.render(); // 性能监控和清理 this.updatePerformanceStats(currentTime); this.performCleanupIfNeeded(currentTime); requestAnimationFrame((time) => this.gameLoop(time)); } update(deltaTime) { // 更新魔法锅 this.pot.update(deltaTime); // 更新粒子系统 this.particleSystem.update(deltaTime); // 更新动物系统 this.animalSystem.update(deltaTime); // 如果正在溢出,生成食物粒子(控制生成频率) if (this.gameState === 'overflowing') { const currentTime = Date.now(); if (currentTime - this.lastFoodSpawnTime >= this.foodSpawnInterval) { this.spawnFoodParticles(); this.lastFoodSpawnTime = currentTime; // 在生成食物粒子后立即检查动物生成 this.checkAnimalSpawn(); this.checkEasterEggs(); } } } spawnFoodParticles() { // 检查是否达到最大粒子数量 if (this.particleSystem.getParticleCount() >= this.config.maxParticles) { this.showDebug('已达到最大粒子数量,停止生成新粒子'); return; } // 检查是否达到最大食物计数 if (this.foodCount >= this.config.maxFoodCount) { this.showDebug('已达到最大食物数量,自动停止烹饪'); this.stopCooking(); return; } // 根据配置生成食物粒子 const spawnCount = Math.min( this.config.particleSpawnRate, this.config.maxParticles - this.particleSystem.getParticleCount(), this.config.maxFoodCount - this.foodCount ); for (let i = 0; i < spawnCount; i++) { const particle = this.particleSystem.createFoodParticle( this.pot.x, this.pot.y - 50, this.currentFood ); // 注意:粒子已经在 createFoodParticle 中添加到 particleSystem.particles 了 // 这里不需要再添加到 this.particles this.foodCount++; console.log(`食物粒子已创建: ${this.currentFood}, 当前计数: ${this.foodCount}`); // 随机播放食物弹出音效 if (this.audio && Math.random() < 0.3) { this.audio.playRandomFoodPop(); } } // 更新UI显示 this.updateUI(); } checkAnimalSpawn() { // 更宽松的动物出现条件 if (this.foodCount >= this.config.animalSpawnThreshold) { // 每2个食物就有机会出现动物,并且增加随机性 if (this.foodCount % 2 === 0 && Math.random() < 0.3) { this.showDebug(`食物数量达到${this.foodCount},尝试生成动物`); this.spawnAnimal(); } } else { // 调试信息:显示距离动物出现还需要多少食物 if (this.foodCount % 2 === 0) { const remaining = this.config.animalSpawnThreshold - this.foodCount; this.showDebug(`还需要${remaining}个食物才能出现动物(当前:${this.foodCount})`); } } } checkEasterEggs() { // 草莓和西瓜的特殊彩蛋 if ((this.currentFood === 'strawberry' || this.currentFood === 'watermelon') && this.foodCount >= this.config.easterEggThreshold) { // 检查是否已经有小女孩了 const hasGirl = this.animalSystem.animals.some(animal => animal.type === 'girl'); if (!hasGirl && this.foodCount % 15 === 0) { this.spawnLittleGirl(); this.showSpecialMessage('小女孩被美味的水果吸引过来了!'); } } // 其他隐藏彩蛋 this.checkSecretEasterEggs(); } checkSecretEasterEggs() { // 特殊组合彩蛋 if (this.foodCount === 100) { this.createCelebrationEffect(); this.showSpecialMessage('恭喜!你制作了100个食物!'); } // 特定食物的特殊效果 if (this.currentFood === 'cake' && this.foodCount >= 20) { this.createBirthdayEffect(); } } spawnAnimal() { // 检查是否达到最大动物数量 if (this.animalSystem.getAnimalCount() >= this.config.maxAnimals) { this.showDebug('已达到最大动物数量,不再生成新动物'); return; } // 检查当前食物是否已设置 if (!this.currentFood) { this.showDebug('当前食物未设置,无法生成动物'); return; } const side = Math.random() < 0.5 ? 'left' : 'right'; console.log(`尝试生成动物: 食物类型=${this.currentFood}, 边=${side}, 当前动物数=${this.animalSystem.getAnimalCount()}`); const animal = this.animalSystem.createAnimal(this.currentFood, side); if (animal) { // 动物已经在 createAnimal 方法中添加到 animalSystem.animals 了 this.showDebug(`🐾 小动物出现了!类型: ${animal.type}, 食物: ${this.currentFood}, 边: ${side}, 总数: ${this.animalSystem.getAnimalCount()}`); // 播放动物出现音效 if (this.audio) { this.audio.playAnimalAppear(); } } else { this.showDebug('❌ 动物生成失败'); } } spawnLittleGirl() { const girl = this.animalSystem.createLittleGirl('right'); if (girl) { // 小女孩已经在 createLittleGirl 方法中添加到 animalSystem.animals 了 this.showDebug('小女孩出现了!'); // 播放小女孩出现音效 if (this.audio) { this.audio.playGirlAppear(); } // 创建特殊效果 this.particleSystem.createSparkleParticles( this.canvas.width - 100, this.canvas.height - 100, 10 ); } } createCelebrationEffect() { // 播放庆祝音效 if (this.audio) { this.audio.playCelebration(); } // 创建庆祝烟花效果 for (let i = 0; i < 5; i++) { setTimeout(() => { const x = Math.random() * this.canvas.width; const y = Math.random() * this.canvas.height * 0.5; this.particleSystem.createExplosionParticles(x, y, 15, '#FFD700'); this.particleSystem.createExplosionParticles(x, y, 15, '#FF69B4'); }, i * 500); } } createBirthdayEffect() { // 生日蛋糕特效 const centerX = this.canvas.width / 2; const centerY = this.canvas.height / 2; this.particleSystem.createSparkleParticles(centerX, centerY, 20); this.showSpecialMessage('生日快乐!🎂'); } showSpecialMessage(message) { // 显示特殊消息 const messageDiv = document.createElement('div'); messageDiv.textContent = message; messageDiv.style.cssText = ` position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: linear-gradient(45deg, #FF6B6B, #4ECDC4); color: white; padding: 20px 30px; border-radius: 15px; font-size: 18px; font-weight: bold; box-shadow: 0 8px 32px rgba(0,0,0,0.3); z-index: 10000; animation: specialMessage 3s ease-in-out forwards; `; document.body.appendChild(messageDiv); setTimeout(() => { if (messageDiv.parentNode) { messageDiv.parentNode.removeChild(messageDiv); } }, 3000); } render() { // 清空画布 this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); // 绘制背景 this.renderBackground(); // 绘制魔法锅 this.pot.render(this.ctx); // 绘制粒子 this.particleSystem.render(this.ctx); // 绘制动物 this.animalSystem.render(this.ctx); // 绘制特效 this.renderEffects(); } renderBackground() { // 绘制渐变背景 const gradient = this.ctx.createLinearGradient(0, 0, 0, this.canvas.height); gradient.addColorStop(0, '#87CEEB'); gradient.addColorStop(1, '#98FB98'); this.ctx.fillStyle = gradient; this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height); // 绘制装饰性元素 this.renderDecorations(); } renderDecorations() { // 绘制云朵 this.ctx.fillStyle = 'rgba(255, 255, 255, 0.8)'; this.drawCloud(100, 80, 60); this.drawCloud(300, 60, 40); this.drawCloud(500, 90, 50); } drawCloud(x, y, size) { this.ctx.beginPath(); this.ctx.arc(x, y, size * 0.5, 0, Math.PI * 2); this.ctx.arc(x + size * 0.3, y, size * 0.6, 0, Math.PI * 2); this.ctx.arc(x + size * 0.6, y, size * 0.4, 0, Math.PI * 2); this.ctx.arc(x - size * 0.3, y, size * 0.4, 0, Math.PI * 2); this.ctx.fill(); } renderEffects() { // 绘制魔法粒子效果 if (this.gameState === 'activated' || this.gameState === 'cooking') { this.renderMagicSparkles(); } } renderMagicSparkles() { const time = Date.now() * 0.005; this.ctx.fillStyle = '#FFD700'; for (let i = 0; i < 5; i++) { const angle = (i / 5) * Math.PI * 2 + time; const radius = 80 + Math.sin(time + i) * 20; const x = this.pot.x + Math.cos(angle) * radius; const y = this.pot.y + Math.sin(angle) * radius; this.ctx.beginPath(); this.ctx.arc(x, y, 3, 0, Math.PI * 2); this.ctx.fill(); } } updateUI() { // 更新锅状态 const potStatus = document.getElementById('potStatus'); const statusIndicator = potStatus.querySelector('.status-indicator'); statusIndicator.className = 'status-indicator'; switch (this.gameState) { case 'idle': statusIndicator.textContent = '魔法锅休眠中'; statusIndicator.classList.add('inactive'); break; case 'activated': statusIndicator.textContent = '魔法锅已激活'; statusIndicator.classList.add('active'); break; case 'cooking': statusIndicator.textContent = '正在烹饪中...'; statusIndicator.classList.add('cooking'); break; case 'overflowing': statusIndicator.textContent = '食物涌出中!'; statusIndicator.classList.add('overflowing'); break; case 'stopped': statusIndicator.textContent = '烹饪已停止'; statusIndicator.classList.add('inactive'); break; } // 更新烹饪信息 const cookingInfo = document.getElementById('cookingInfo'); const currentFoodSpan = document.getElementById('currentFood'); if (this.gameState === 'cooking' && this.currentFood) { cookingInfo.style.display = 'block'; currentFoodSpan.textContent = this.currentFood; } else { cookingInfo.style.display = 'none'; } // 更新食物计数器 const foodCounter = document.getElementById('foodCounter'); const foodCount = document.getElementById('foodCount'); const foodEmoji = document.getElementById('foodEmoji'); if (this.gameState === 'overflowing' || this.gameState === 'stopped') { foodCounter.style.display = 'block'; foodCount.textContent = this.foodCount; foodEmoji.textContent = this.getFoodEmoji(this.currentFood); } else { foodCounter.style.display = 'none'; } // 更新语音提示 this.updateVoiceHints(); // 更新性能监控 this.updatePerformanceDisplay(); } updateVoiceHints() { const foodHint = document.getElementById('foodHint'); const stopHint = document.getElementById('stopHint'); foodHint.style.display = this.gameState === 'activated' ? 'block' : 'none'; stopHint.style.display = this.gameState === 'overflowing' ? 'block' : 'none'; } updatePerformanceDisplay() { const performanceMonitor = document.getElementById('performanceMonitor'); const particleCount = document.getElementById('particleCount'); const animalCount = document.getElementById('animalCount'); const fpsCount = document.getElementById('fpsCount'); if (performanceMonitor && particleCount && animalCount && fpsCount) { const perfInfo = this.getPerformanceInfo(); particleCount.textContent = perfInfo.particles; animalCount.textContent = perfInfo.animals; fpsCount.textContent = perfInfo.fps; // 根据游戏状态显示/隐藏性能监控 const shouldShow = this.gameState === 'overflowing' || this.gameState === 'cooking' || perfInfo.particles > 50; performanceMonitor.style.display = shouldShow ? 'block' : 'none'; // 性能警告颜色 if (perfInfo.particles > this.config.maxParticles * 0.8) { particleCount.style.color = '#ff6b6b'; } else { particleCount.style.color = '#ffffff'; } if (perfInfo.animals > this.config.maxAnimals * 0.8) { animalCount.style.color = '#ff6b6b'; } else { animalCount.style.color = '#ffffff'; } if (perfInfo.fps < 30) { fpsCount.style.color = '#ff6b6b'; } else if (perfInfo.fps < 45) { fpsCount.style.color = '#f39c12'; } else { fpsCount.style.color = '#27ae60'; } } } updateCookingProgress(progress) { const progressFill = document.getElementById('progressFill'); if (progressFill) { progressFill.style.width = progress + '%'; } } updateVoiceStatus(status) { const voiceStatus = document.getElementById('voiceStatus'); const statusText = voiceStatus.querySelector('.status-text'); switch (status) { case 'listening': statusText.textContent = '正在听取...'; voiceStatus.style.background = '#e74c3c'; break; case 'processing': statusText.textContent = '处理中...'; voiceStatus.style.background = '#f39c12'; break; case 'ready': statusText.textContent = '准备就绪'; voiceStatus.style.background = '#4ecdc4'; break; case 'error': statusText.textContent = '语音错误'; voiceStatus.style.background = '#95a5a6'; break; } } getFoodEmoji(foodName) { const emojiMap = { 'apple': '🍎', 'banana': '🍌', 'orange': '🍊', 'strawberry': '🍓', 'watermelon': '🍉', 'grape': '🍇', 'pizza': '🍕', 'burger': '🍔', 'cake': '🍰', 'cookie': '🍪', 'bread': '🍞', 'cheese': '🧀' }; return emojiMap[foodName] || '🍽️'; } showDebug(message) { const debugLog = document.getElementById('debugLog'); if (debugLog) { const time = new Date().toLocaleTimeString(); const perfInfo = this.getPerformanceInfo(); const perfText = `FPS:${perfInfo.fps} P:${perfInfo.particles} A:${perfInfo.animals} M:${perfInfo.memoryUsage}KB`; debugLog.innerHTML += `
说出:"cook cook cook pot"
其他可用命令:
魔法锅激活后,说出任何食物名称:
说出:"stop stop stop pot"
其他可用命令:
💡 面板默认隐藏,按F9激活并显示面板后才能输入命令
🖱️ 激活后可拖拽标题栏移动面板,按F5重置到右下角
👁️ 按F8可手动显示/隐藏面板,取消激活时自动隐藏