// 英语学习网页主脚本 // 游戏状态 let gameState = { currentSceneIndex: 0, currentDialogIndex: 0, score: 0, totalQuestions: 0, correctAnswers: 0 }; // DOM元素 let elements; // 在DOM加载完成后获取DOM元素 function getDomElements() { elements = { scoreElement: document.getElementById('score'), progressElement: document.getElementById('progress'), sceneTitle: document.getElementById('scene-title'), sceneDescription: document.getElementById('scene-description'), sceneImage: document.getElementById('scene-image'), conversation: document.getElementById('conversation'), questionArea: document.getElementById('question-area'), questionText: document.getElementById('question-text'), options: document.querySelectorAll('.option'), feedback: document.getElementById('feedback'), feedbackText: document.getElementById('feedback-text'), startButton: document.getElementById('start-button'), resetButton: document.getElementById('reset-button'), nextSceneButton: document.getElementById('next-scene-button') }; } // 初始化游戏 function initGame() { resetGameState(); loadScene(gameState.currentSceneIndex); setupEventListeners(); updateProgress(); } // 重置游戏状态 function resetGameState() { gameState = { currentSceneIndex: 0, currentDialogIndex: 0, score: 0, totalQuestions: 0, correctAnswers: 0 }; } // 加载场景 function loadScene(sceneIndex) { if (sceneIndex >= englishData.scenes.length) { showGameComplete(); return; } const scene = englishData.scenes[sceneIndex]; // 更新场景信息 elements.sceneTitle.textContent = scene.title; elements.sceneDescription.textContent = scene.description; // 加载场景图片 // 简化的图片加载逻辑:优先使用场景ID作为图片名称 let imagePath = scene.image; // 确保图片元素存在 if (!elements.sceneImage) { console.error('场景图片元素不存在'); return; } // 重置图片状态 elements.sceneImage.src = ''; elements.sceneImage.alt = scene.title + '场景插图'; elements.sceneImage.style.display = 'none'; // 如果没有指定图片路径,则使用场景ID作为图片名称自动查找 if (!imagePath) { // 简单的命名规则:images/[场景ID].[扩展名] 或 images/[场景标题拼音].[扩展名] const possibleExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.bmp', '.svg']; const baseNameId = scene.id.toString(); // 将场景标题转换为拼音风格的文件名(去掉空格和特殊字符,转为小写) const baseNameTitle = scene.title .replace(/[^\u4e00-\u9fa5a-zA-Z0-9]/g, '') // 保留中英文数字 .toLowerCase(); // 所有可能的图片路径(优先ID命名,然后标题拼音命名) const allPossiblePaths = [ // 优先使用ID命名 ...possibleExtensions.map(ext => `images/${baseNameId}${ext}`), // 也支持标题拼音命名 ...possibleExtensions.map(ext => `images/${baseNameTitle}${ext}`) ]; console.log('尝试查找图片路径:', allPossiblePaths); // 递归检查图片是否存在 function checkImage(index) { if (index >= allPossiblePaths.length) { console.log('未找到任何图片'); return; } const potentialPath = allPossiblePaths[index]; console.log('尝试加载图片:', potentialPath); const img = new Image(); img.onload = function() { console.log('图片加载成功:', potentialPath); // 图片存在,设置路径并显示 elements.sceneImage.src = potentialPath; elements.sceneImage.style.display = 'block'; }; img.onerror = function() { console.log('图片加载失败:', potentialPath); // 图片不存在,检查下一个 checkImage(index + 1); }; img.src = potentialPath; } // 开始检查 checkImage(0); } else { console.log('使用指定的图片路径:', imagePath); // 使用指定的图片路径 elements.sceneImage.src = imagePath; elements.sceneImage.onload = function() { elements.sceneImage.style.display = 'block'; }; elements.sceneImage.onerror = function() { console.error('指定的图片路径加载失败:', imagePath); elements.sceneImage.style.display = 'none'; }; } // 清空对话区域 elements.conversation.innerHTML = ''; // 重置对话索引 gameState.currentDialogIndex = 0; // 显示第一个对话 showNextDialog(); // 更新进度 updateProgress(); // 隐藏下一场景按钮 elements.nextSceneButton.disabled = true; } // 显示下一个对话 function showNextDialog() { const scene = englishData.scenes[gameState.currentSceneIndex]; const conversation = scene.conversation; if (gameState.currentDialogIndex >= conversation.length) { // 当前场景对话结束 if (gameState.currentSceneIndex < englishData.scenes.length - 1) { elements.nextSceneButton.disabled = false; } return; } const dialog = conversation[gameState.currentDialogIndex]; if (dialog.type === 'user_question') { // 显示选择题 showQuestion(dialog); } else { // 显示普通对话 addMessage(dialog); // 自动显示下一个对话 gameState.currentDialogIndex++; setTimeout(showNextDialog, 1000); } } // 添加对话消息 function addMessage(dialog) { const messageDiv = document.createElement('div'); messageDiv.className = `message ${dialog.type}`; const speakerSpan = document.createElement('span'); speakerSpan.className = 'speaker'; speakerSpan.textContent = dialog.speaker + ':'; const textSpan = document.createElement('span'); textSpan.className = 'text'; textSpan.textContent = dialog.text; messageDiv.appendChild(speakerSpan); messageDiv.appendChild(textSpan); elements.conversation.appendChild(messageDiv); // 滚动到底部 elements.conversation.scrollTop = elements.conversation.scrollHeight; } // 显示选择题 function showQuestion(dialog) { elements.questionText.textContent = dialog.question; // 复制选项数组并打乱顺序 const originalOptions = [...dialog.options]; const shuffledOptions = [...originalOptions]; // 使用Fisher-Yates算法打乱选项 for (let i = shuffledOptions.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [shuffledOptions[i], shuffledOptions[j]] = [shuffledOptions[j], shuffledOptions[i]]; } // 计算正确答案在打乱后的新位置 const correctAnswerText = originalOptions[dialog.correctAnswer]; const newCorrectIndex = shuffledOptions.indexOf(correctAnswerText); // 保存原始选项和新的正确答案索引到对话对象中,供后续检查使用 dialog.originalOptions = originalOptions; dialog.shuffledOptions = shuffledOptions; dialog.shuffledCorrectAnswer = newCorrectIndex; // 设置打乱后的选项 elements.options.forEach((option, index) => { option.textContent = shuffledOptions[index]; option.disabled = false; option.classList.remove('selected', 'correct', 'incorrect'); }); // 显示选择题区域 elements.questionArea.style.display = 'block'; elements.feedback.style.display = 'none'; } // 处理选项选择 function handleOptionSelect(selectedOptionIndex) { const scene = englishData.scenes[gameState.currentSceneIndex]; const dialog = scene.conversation[gameState.currentDialogIndex]; // 使用打乱后的正确答案索引 const correctAnswerIndex = dialog.shuffledCorrectAnswer !== undefined ? dialog.shuffledCorrectAnswer : dialog.correctAnswer; // 禁用所有选项 elements.options.forEach(option => { option.disabled = true; }); // 标记选择的选项 const selectedOption = elements.options[selectedOptionIndex]; selectedOption.classList.add('selected'); // 检查答案 gameState.totalQuestions++; let isCorrect = false; if (selectedOptionIndex === correctAnswerIndex) { // 正确答案 gameState.score += 10; gameState.correctAnswers++; selectedOption.classList.add('correct'); showFeedback(true, dialog); isCorrect = true; } else { // 错误答案 selectedOption.classList.add('incorrect'); elements.options[correctAnswerIndex].classList.add('correct'); showFeedback(false, dialog); } // 更新得分和进度 updateProgress(); // 添加用户选择的对话 addUserChoiceToConversation(dialog, selectedOptionIndex, isCorrect); // 延迟后显示下一个对话 setTimeout(() => { gameState.currentDialogIndex++; elements.questionArea.style.display = 'none'; elements.feedback.style.display = 'none'; showNextDialog(); }, 3000); } // 添加用户选择到对话 function addUserChoiceToConversation(dialog, selectedIndex, isCorrect) { const userMessage = { speaker: dialog.speaker, text: dialog.options[selectedIndex], type: 'user' }; addMessage(userMessage); } // 显示反馈 function showFeedback(isCorrect, dialog) { const feedbackTextElement = elements.feedbackText; if (isCorrect) { // 正确答案 feedbackTextElement.textContent = '正确! 很好的回答。'; feedbackTextElement.className = 'correct'; elements.feedback.style.borderColor = '#4CAF50'; elements.feedback.style.backgroundColor = '#e8f5e8'; } else { // 错误答案 // 根据是否有打乱后的选项来选择使用哪个数组 const correctAnswer = dialog.shuffledOptions && dialog.shuffledCorrectAnswer !== undefined ? dialog.shuffledOptions[dialog.shuffledCorrectAnswer] : dialog.options[dialog.correctAnswer]; feedbackTextElement.textContent = `不正确。正确答案是: ${correctAnswer}`; feedbackTextElement.className = 'incorrect'; elements.feedback.style.borderColor = '#f44336'; elements.feedback.style.backgroundColor = '#ffebee'; } elements.feedback.style.display = 'block'; } // 更新进度 function updateProgress() { elements.scoreElement.textContent = `得分: ${gameState.score}`; elements.progressElement.textContent = `进度: ${gameState.currentSceneIndex + 1}/${englishData.scenes.length}`; } // 显示游戏完成信息 function showGameComplete() { elements.conversation.innerHTML = ''; elements.questionArea.style.display = 'none'; const completeMessage = document.createElement('div'); completeMessage.className = 'message other'; completeMessage.innerHTML = ` 学习完成: 恭喜您完成了所有场景的学习!
总得分: ${gameState.score}
正确题目: ${gameState.correctAnswers}/${gameState.totalQuestions}
`; elements.conversation.appendChild(completeMessage); elements.nextSceneButton.disabled = true; } // 设置事件监听器 function setupEventListeners() { // 选项按钮点击事件 elements.options.forEach((option, index) => { option.addEventListener('click', () => { handleOptionSelect(index); }); }); // 开始按钮点击事件 elements.startButton.addEventListener('click', () => { initGame(); elements.startButton.style.display = 'none'; }); // 重置按钮点击事件 elements.resetButton.addEventListener('click', () => { initGame(); elements.startButton.style.display = 'none'; }); // 下一场景按钮点击事件 elements.nextSceneButton.addEventListener('click', () => { gameState.currentSceneIndex++; loadScene(gameState.currentSceneIndex); }); } // 页面加载完成后初始化游戏 document.addEventListener('DOMContentLoaded', () => { // 获取DOM元素 getDomElements(); // 确保englishData已加载 if (typeof englishData !== 'undefined') { initGame(); elements.startButton.style.display = 'block'; } else { console.error('英语学习数据未加载'); } });