Spaces:
Running
Running
| <html lang="zh-CN"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>小学自然拼读游戏</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| @keyframes bounce { | |
| 0%, 100% { transform: translateY(0); } | |
| 50% { transform: translateY(-10px); } | |
| } | |
| .bounce { | |
| animation: bounce 1s infinite; | |
| } | |
| .letter-card { | |
| transition: all 0.3s ease; | |
| } | |
| .letter-card:hover { | |
| transform: scale(1.1); | |
| box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); | |
| } | |
| .word-card { | |
| transition: all 0.3s ease; | |
| } | |
| .word-card:hover { | |
| transform: translateY(-5px); | |
| } | |
| .progress-bar { | |
| transition: width 0.5s ease; | |
| } | |
| .confetti { | |
| position: absolute; | |
| width: 10px; | |
| height: 10px; | |
| background-color: #f00; | |
| opacity: 0; | |
| } | |
| @keyframes confetti-fall { | |
| 0% { transform: translateY(-100px) rotate(0deg); opacity: 1; } | |
| 100% { transform: translateY(100vh) rotate(360deg); opacity: 0; } | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-blue-50 min-h-screen font-sans"> | |
| <div class="container mx-auto px-4 py-8"> | |
| <!-- 标题和导航 --> | |
| <header class="text-center mb-8"> | |
| <h1 class="text-4xl font-bold text-blue-600 mb-2">自然拼读小乐园</h1> | |
| <p class="text-lg text-gray-600">快乐学习英语发音,轻松掌握拼读技巧</p> | |
| <div class="flex justify-center mt-4 space-x-4"> | |
| <button id="letters-tab" class="px-4 py-2 bg-blue-500 text-white rounded-lg font-medium hover:bg-blue-600 transition">字母发音</button> | |
| <button id="words-tab" class="px-4 py-2 bg-blue-200 text-blue-700 rounded-lg font-medium hover:bg-blue-300 transition">单词拼读</button> | |
| <button id="game-tab" class="px-4 py-2 bg-blue-200 text-blue-700 rounded-lg font-medium hover:bg-blue-300 transition">拼读游戏</button> | |
| </div> | |
| </header> | |
| <!-- 进度条 --> | |
| <div class="bg-white rounded-lg shadow-md p-4 mb-6"> | |
| <div class="flex justify-between items-center mb-2"> | |
| <span class="font-medium text-gray-700">学习进度</span> | |
| <span id="progress-percent" class="font-bold text-blue-600">0%</span> | |
| </div> | |
| <div class="w-full bg-gray-200 rounded-full h-4"> | |
| <div id="progress-bar" class="progress-bar h-4 rounded-full bg-blue-500" style="width: 0%"></div> | |
| </div> | |
| </div> | |
| <!-- 字母发音部分 --> | |
| <section id="letters-section" class="mb-8"> | |
| <h2 class="text-2xl font-bold text-blue-500 mb-4 flex items-center"> | |
| <i class="fas fa-font mr-2"></i> 字母发音 | |
| </h2> | |
| <div class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6 gap-4"> | |
| <!-- 字母卡片将通过JavaScript动态生成 --> | |
| </div> | |
| </section> | |
| <!-- 单词拼读部分 --> | |
| <section id="words-section" class="mb-8 hidden"> | |
| <h2 class="text-2xl font-bold text-blue-500 mb-4 flex items-center"> | |
| <i class="fas fa-spell-check mr-2"></i> 单词拼读 | |
| </h2> | |
| <div class="mb-6"> | |
| <div class="flex flex-wrap gap-2 mb-4"> | |
| <button class="word-category px-3 py-1 bg-blue-100 text-blue-700 rounded-full hover:bg-blue-200 transition" data-category="cvc">CVC单词</button> | |
| <button class="word-category px-3 py-1 bg-blue-100 text-blue-700 rounded-full hover:bg-blue-200 transition" data-category="cvce">CVCe单词</button> | |
| <button class="word-category px-3 py-1 bg-blue-100 text-blue-700 rounded-full hover:bg-blue-200 transition" data-category="blends">混合音</button> | |
| <button class="word-category px-3 py-1 bg-blue-100 text-blue-700 rounded-full hover:bg-blue-200 transition" data-category="digraphs">双字母音</button> | |
| </div> | |
| <div class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-4" id="words-container"> | |
| <!-- 单词卡片将通过JavaScript动态生成 --> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- 拼读游戏部分 --> | |
| <section id="game-section" class="hidden"> | |
| <h2 class="text-2xl font-bold text-blue-500 mb-4 flex items-center"> | |
| <i class="fas fa-gamepad mr-2"></i> 拼读游戏 | |
| </h2> | |
| <div class="bg-white rounded-xl shadow-lg p-6"> | |
| <div id="game-start" class="text-center"> | |
| <h3 class="text-xl font-bold text-gray-800 mb-4">选择游戏难度</h3> | |
| <div class="flex justify-center space-x-4 mb-6"> | |
| <button class="game-level px-6 py-3 bg-green-100 text-green-700 rounded-lg font-medium hover:bg-green-200 transition" data-level="easy"> | |
| <i class="fas fa-star mr-2"></i>简单 | |
| </button> | |
| <button class="game-level px-6 py-3 bg-yellow-100 text-yellow-700 rounded-lg font-medium hover:bg-yellow-200 transition" data-level="medium"> | |
| <i class="fas fa-star-half-alt mr-2"></i>中等 | |
| </button> | |
| <button class="game-level px-6 py-3 bg-red-100 text-red-700 rounded-lg font-medium hover:bg-red-200 transition" data-level="hard"> | |
| <i class="fas fa-star mr-2"></i>困难 | |
| </button> | |
| </div> | |
| <div class="max-w-md mx-auto bg-blue-50 p-4 rounded-lg"> | |
| <h4 class="font-bold text-blue-600 mb-2">游戏说明</h4> | |
| <p class="text-gray-700 text-sm">听发音,选择正确的字母或单词。每关有5道题,答对越多得分越高!</p> | |
| </div> | |
| </div> | |
| <div id="game-play" class="hidden"> | |
| <div class="flex justify-between items-center mb-6"> | |
| <div class="text-lg font-bold text-blue-600">第 <span id="current-question">1</span>/5 题</div> | |
| <div class="text-lg font-bold text-green-600">得分: <span id="game-score">0</span></div> | |
| </div> | |
| <div class="bg-blue-100 rounded-xl p-6 mb-6 text-center"> | |
| <div id="game-question" class="text-4xl font-bold text-gray-800 mb-4"></div> | |
| <button id="play-sound" class="px-6 py-3 bg-blue-500 text-white rounded-lg font-medium hover:bg-blue-600 transition"> | |
| <i class="fas fa-volume-up mr-2"></i>播放发音 | |
| </button> | |
| </div> | |
| <div id="game-options" class="grid grid-cols-2 gap-4"> | |
| <!-- 游戏选项将通过JavaScript动态生成 --> | |
| </div> | |
| </div> | |
| <div id="game-result" class="hidden text-center py-8"> | |
| <div id="result-icon" class="text-6xl mb-4"></div> | |
| <h3 id="result-title" class="text-2xl font-bold mb-2"></h3> | |
| <p id="result-message" class="text-gray-700 mb-6"></p> | |
| <div class="text-xl font-bold text-blue-600 mb-6">你的得分: <span id="final-score">0</span>/100</div> | |
| <button id="play-again" class="px-6 py-3 bg-blue-500 text-white rounded-lg font-medium hover:bg-blue-600 transition"> | |
| <i class="fas fa-redo mr-2"></i>再玩一次 | |
| </button> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- 发音模态框 --> | |
| <div id="pronunciation-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden"> | |
| <div class="bg-white rounded-xl p-6 max-w-md w-full mx-4"> | |
| <div class="flex justify-between items-center mb-4"> | |
| <h3 class="text-xl font-bold text-blue-600" id="modal-title">字母发音</h3> | |
| <button id="close-modal" class="text-gray-500 hover:text-gray-700"> | |
| <i class="fas fa-times"></i> | |
| </button> | |
| </div> | |
| <div class="text-center py-4"> | |
| <div id="modal-content" class="text-8xl font-bold text-blue-500 mb-4"></div> | |
| <button id="play-modal-sound" class="px-6 py-3 bg-blue-500 text-white rounded-lg font-medium hover:bg-blue-600 transition"> | |
| <i class="fas fa-volume-up mr-2"></i>播放发音 | |
| </button> | |
| </div> | |
| <div class="mt-4 text-sm text-gray-600" id="modal-tips"></div> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // 字母数据 | |
| const letters = [ | |
| { letter: 'A', sound: 'a', example: 'apple', color: 'red' }, | |
| { letter: 'B', sound: 'b', example: 'ball', color: 'blue' }, | |
| { letter: 'C', sound: 'k', example: 'cat', color: 'green' }, | |
| { letter: 'D', sound: 'd', example: 'dog', color: 'yellow' }, | |
| { letter: 'E', sound: 'e', example: 'egg', color: 'purple' }, | |
| { letter: 'F', sound: 'f', example: 'fish', color: 'pink' }, | |
| { letter: 'G', sound: 'g', example: 'goat', color: 'orange' }, | |
| { letter: 'H', sound: 'h', example: 'hat', color: 'teal' }, | |
| { letter: 'I', sound: 'i', example: 'igloo', color: 'indigo' }, | |
| { letter: 'J', sound: 'j', example: 'jam', color: 'amber' }, | |
| { letter: 'K', sound: 'k', example: 'kite', color: 'lime' }, | |
| { letter: 'L', sound: 'l', example: 'lion', color: 'cyan' }, | |
| { letter: 'M', sound: 'm', example: 'monkey', color: 'rose' }, | |
| { letter: 'N', sound: 'n', example: 'nest', color: 'emerald' }, | |
| { letter: 'O', sound: 'o', example: 'octopus', color: 'violet' }, | |
| { letter: 'P', sound: 'p', example: 'pig', color: 'fuchsia' }, | |
| { letter: 'Q', sound: 'kw', example: 'queen', color: 'lightBlue' }, | |
| { letter: 'R', sound: 'r', example: 'rabbit', color: 'lightGreen' }, | |
| { letter: 'S', sound: 's', example: 'sun', color: 'deepOrange' }, | |
| { letter: 'T', sound: 't', example: 'tiger', color: 'deepPurple' }, | |
| { letter: 'U', sound: 'u', example: 'umbrella', color: 'brown' }, | |
| { letter: 'V', sound: 'v', example: 'van', color: 'blueGray' }, | |
| { letter: 'W', sound: 'w', example: 'water', color: 'warmGray' }, | |
| { letter: 'X', sound: 'ks', example: 'box', color: 'trueGray' }, | |
| { letter: 'Y', sound: 'y', example: 'yellow', color: 'coolGray' }, | |
| { letter: 'Z', sound: 'z', example: 'zebra', color: 'stone' } | |
| ]; | |
| // 单词数据 | |
| const words = { | |
| cvc: [ | |
| { word: 'cat', sound: 'k-a-t', image: '🐱' }, | |
| { word: 'dog', sound: 'd-o-g', image: '🐶' }, | |
| { word: 'pen', sound: 'p-e-n', image: '🖊️' }, | |
| { word: 'hat', sound: 'h-a-t', image: '🧢' }, | |
| { word: 'sun', sound: 's-u-n', image: '☀️' }, | |
| { word: 'bed', sound: 'b-e-d', image: '🛏️' }, | |
| { word: 'pig', sound: 'p-i-g', image: '🐷' }, | |
| { word: 'cup', sound: 'c-u-p', image: '🥤' } | |
| ], | |
| cvce: [ | |
| { word: 'cake', sound: 'k-ay-k', image: '🍰' }, | |
| { word: 'bike', sound: 'b-ay-k', image: '🚲' }, | |
| { word: 'home', sound: 'h-ow-m', image: '🏠' }, | |
| { word: 'cube', sound: 'k-yoo-b', image: '🧊' }, | |
| { word: 'pine', sound: 'p-ay-n', image: '🌲' }, | |
| { word: 'kite', sound: 'k-ay-t', image: '🪁' }, | |
| { word: 'rope', sound: 'r-ow-p', image: '🧶' }, | |
| { word: 'mule', sound: 'm-yoo-l', image: '🐴' } | |
| ], | |
| blends: [ | |
| { word: 'frog', sound: 'f-r-o-g', image: '🐸' }, | |
| { word: 'star', sound: 's-t-ar', image: '⭐' }, | |
| { word: 'tree', sound: 't-r-ee', image: '🌳' }, | |
| { word: 'flag', sound: 'f-l-a-g', image: '🚩' }, | |
| { word: 'sled', sound: 's-l-e-d', image: '🛷' }, | |
| { word: 'brush', sound: 'b-r-u-sh', image: '🪥' }, | |
| { word: 'crab', sound: 'k-r-a-b', image: '🦀' }, | |
| { word: 'swim', sound: 's-w-i-m', image: '🏊' } | |
| ], | |
| digraphs: [ | |
| { word: 'ship', sound: 'sh-i-p', image: '🚢' }, | |
| { word: 'chin', sound: 'ch-i-n', image: '👦' }, | |
| { word: 'thin', sound: 'th-i-n', image: '👕' }, | |
| { word: 'when', sound: 'wh-e-n', image: '⏰' }, | |
| { word: 'photo', sound: 'f-ow-t-ow', image: '📷' }, | |
| { word: 'cheese', sound: 'ch-ee-z', image: '🧀' }, | |
| { word: 'whale', sound: 'wh-ay-l', image: '🐋' }, | |
| { word: 'shoes', sound: 'sh-oo-z', image: '👟' } | |
| ] | |
| }; | |
| // 游戏数据 | |
| const gameQuestions = { | |
| easy: [ | |
| { type: 'letter', question: 'A', options: ['A', 'B', 'C', 'D'], answer: 'A' }, | |
| { type: 'letter', question: 'B', options: ['A', 'B', 'C', 'D'], answer: 'B' }, | |
| { type: 'letter', question: 'C', options: ['A', 'B', 'C', 'D'], answer: 'C' }, | |
| { type: 'letter', question: 'D', options: ['A', 'B', 'C', 'D'], answer: 'D' }, | |
| { type: 'letter', question: 'E', options: ['E', 'F', 'G', 'H'], answer: 'E' } | |
| ], | |
| medium: [ | |
| { type: 'word', question: 'cat', options: ['cat', 'dog', 'pen', 'hat'], answer: 'cat' }, | |
| { type: 'word', question: 'dog', options: ['cat', 'dog', 'pen', 'hat'], answer: 'dog' }, | |
| { type: 'word', question: 'pen', options: ['cat', 'dog', 'pen', 'hat'], answer: 'pen' }, | |
| { type: 'word', question: 'hat', options: ['cat', 'dog', 'pen', 'hat'], answer: 'hat' }, | |
| { type: 'word', question: 'sun', options: ['sun', 'bed', 'pig', 'cup'], answer: 'sun' } | |
| ], | |
| hard: [ | |
| { type: 'word', question: 'cake', options: ['cake', 'bike', 'home', 'cube'], answer: 'cake' }, | |
| { type: 'word', question: 'frog', options: ['frog', 'star', 'tree', 'flag'], answer: 'frog' }, | |
| { type: 'word', question: 'ship', options: ['ship', 'chin', 'thin', 'when'], answer: 'ship' }, | |
| { type: 'word', question: 'photo', options: ['photo', 'cheese', 'whale', 'shoes'], answer: 'photo' }, | |
| { type: 'word', question: 'brush', options: ['brush', 'crab', 'swim', 'sled'], answer: 'brush' } | |
| ] | |
| }; | |
| // 用户学习进度 | |
| let userProgress = { | |
| letters: Array(letters.length).fill(false), | |
| words: { | |
| cvc: Array(words.cvc.length).fill(false), | |
| cvce: Array(words.cvce.length).fill(false), | |
| blends: Array(words.blends.length).fill(false), | |
| digraphs: Array(words.digraphs.length).fill(false) | |
| }, | |
| games: { | |
| easy: 0, | |
| medium: 0, | |
| hard: 0 | |
| } | |
| }; | |
| // 从本地存储加载进度 | |
| function loadProgress() { | |
| const savedProgress = localStorage.getItem('phonicsProgress'); | |
| if (savedProgress) { | |
| userProgress = JSON.parse(savedProgress); | |
| } | |
| updateProgressBar(); | |
| } | |
| // 保存进度到本地存储 | |
| function saveProgress() { | |
| localStorage.setItem('phonicsProgress', JSON.stringify(userProgress)); | |
| updateProgressBar(); | |
| } | |
| // 更新进度条 | |
| function updateProgressBar() { | |
| // 计算字母学习进度 | |
| const lettersLearned = userProgress.letters.filter(l => l).length; | |
| const lettersTotal = letters.length; | |
| const lettersProgress = lettersLearned / lettersTotal; | |
| // 计算单词学习进度 | |
| let wordsLearned = 0; | |
| let wordsTotal = 0; | |
| for (const category in userProgress.words) { | |
| wordsLearned += userProgress.words[category].filter(w => w).length; | |
| wordsTotal += userProgress.words[category].length; | |
| } | |
| const wordsProgress = wordsLearned / wordsTotal; | |
| // 计算游戏进度 | |
| const gamesProgress = (userProgress.games.easy + userProgress.games.medium + userProgress.games.hard) / 15; | |
| // 计算总进度 (字母40%, 单词40%, 游戏20%) | |
| const totalProgress = (lettersProgress * 0.4 + wordsProgress * 0.4 + gamesProgress * 0.2) * 100; | |
| document.getElementById('progress-bar').style.width = `${totalProgress}%`; | |
| document.getElementById('progress-percent').textContent = `${Math.round(totalProgress)}%`; | |
| } | |
| // 初始化字母卡片 | |
| function initLetters() { | |
| const lettersContainer = document.querySelector('#letters-section .grid'); | |
| lettersContainer.innerHTML = ''; | |
| letters.forEach((letter, index) => { | |
| const card = document.createElement('div'); | |
| card.className = `letter-card bg-white rounded-xl shadow-md p-4 text-center cursor-pointer hover:shadow-lg transition ${userProgress.letters[index] ? 'border-2 border-green-400' : ''}`; | |
| card.innerHTML = ` | |
| <div class="text-6xl font-bold text-${letter.color}-500 mb-2">${letter.letter}</div> | |
| <div class="text-sm text-gray-600">发音: ${letter.sound}</div> | |
| <div class="text-xs text-gray-500 mt-1">例: ${letter.example}</div> | |
| ${userProgress.letters[index] ? '<div class="mt-2 text-green-500"><i class="fas fa-check-circle"></i></div>' : ''} | |
| `; | |
| card.addEventListener('click', () => showLetterModal(letter, index)); | |
| lettersContainer.appendChild(card); | |
| }); | |
| } | |
| // 显示字母发音模态框 | |
| function showLetterModal(letter, index) { | |
| document.getElementById('modal-title').textContent = `字母 ${letter.letter} 的发音`; | |
| document.getElementById('modal-content').textContent = letter.letter; | |
| document.getElementById('modal-tips').innerHTML = ` | |
| <p><strong>发音:</strong> /${letter.sound}/</p> | |
| <p><strong>例词:</strong> ${letter.example}</p> | |
| <p class="mt-2">发音时注意: ${getLetterTip(letter.letter)}</p> | |
| `; | |
| document.getElementById('pronunciation-modal').classList.remove('hidden'); | |
| // 设置播放发音按钮的事件 | |
| document.getElementById('play-modal-sound').onclick = function() { | |
| speakLetter(letter.letter.toLowerCase()); | |
| // 标记为已学习 | |
| if (!userProgress.letters[index]) { | |
| userProgress.letters[index] = true; | |
| saveProgress(); | |
| initLetters(); | |
| } | |
| }; | |
| } | |
| // 获取字母发音提示 | |
| function getLetterTip(letter) { | |
| const tips = { | |
| 'A': '嘴巴张大,像医生检查喉咙时那样说"啊"', | |
| 'B': '双唇紧闭,然后突然分开,发出"b"的音', | |
| 'C': '舌后部抬起,抵住软腭,然后突然放开,发出"k"的音', | |
| 'D': '舌尖抵住上齿龈,然后突然放开,发出"d"的音', | |
| 'E': '嘴巴微微张开,像微笑时那样说"e"', | |
| 'F': '上齿轻触下唇,气流从缝隙中通过,发出"f"的音', | |
| 'G': '舌后部抬起,抵住软腭,然后突然放开,发出"g"的音', | |
| 'H': '嘴巴微微张开,气流从喉咙通过,发出"h"的音', | |
| 'I': '嘴巴微微张开,像微笑时那样说"i"', | |
| 'J': '舌面抬起,靠近硬腭,发出"j"的音', | |
| 'K': '同C的发音,舌后部抬起,抵住软腭,然后突然放开', | |
| 'L': '舌尖抵住上齿龈,气流从舌侧通过,发出"l"的音', | |
| 'M': '双唇紧闭,气流从鼻腔通过,发出"m"的音', | |
| 'N': '舌尖抵住上齿龈,气流从鼻腔通过,发出"n"的音', | |
| 'O': '嘴巴圆圆的,像说"哦"那样', | |
| 'P': '双唇紧闭,然后突然分开,发出"p"的音', | |
| 'Q': '发音同"kw",先发k的音,然后快速滑向w的音', | |
| 'R': '舌尖卷起,靠近硬腭,发出"r"的音', | |
| 'S': '舌尖靠近上齿龈,气流从缝隙中通过,发出"s"的音', | |
| 'T': '舌尖抵住上齿龈,然后突然放开,发出"t"的音', | |
| 'U': '嘴巴撅起,像说"呜"那样', | |
| 'V': '上齿轻触下唇,声带振动,发出"v"的音', | |
| 'W': '双唇收圆,向前突出,发出"w"的音', | |
| 'X': '发音同"ks",先发k的音,然后快速滑向s的音', | |
| 'Y': '舌前部抬起,靠近硬腭,发出"y"的音', | |
| 'Z': '舌尖靠近上齿龈,声带振动,发出"z"的音' | |
| }; | |
| return tips[letter] || '跟着老师多练习几次吧!'; | |
| } | |
| // 初始化单词卡片 | |
| function initWords(category = 'cvc') { | |
| const wordsContainer = document.getElementById('words-container'); | |
| wordsContainer.innerHTML = ''; | |
| words[category].forEach((word, index) => { | |
| const card = document.createElement('div'); | |
| card.className = `word-card bg-white rounded-xl shadow-md p-4 text-center cursor-pointer hover:shadow-lg transition ${userProgress.words[category][index] ? 'border-2 border-green-400' : ''}`; | |
| card.innerHTML = ` | |
| <div class="text-4xl mb-2">${word.image}</div> | |
| <div class="text-xl font-bold text-gray-800 mb-1">${word.word}</div> | |
| <div class="text-sm text-gray-600">${word.sound.split('-').join(' ')}</div> | |
| ${userProgress.words[category][index] ? '<div class="mt-2 text-green-500"><i class="fas fa-check-circle"></i></div>' : ''} | |
| `; | |
| card.addEventListener('click', () => { | |
| speakWord(word.word); | |
| // 标记为已学习 | |
| if (!userProgress.words[category][index]) { | |
| userProgress.words[category][index] = true; | |
| saveProgress(); | |
| initWords(category); | |
| } | |
| }); | |
| wordsContainer.appendChild(card); | |
| }); | |
| // 更新分类按钮状态 | |
| document.querySelectorAll('.word-category').forEach(btn => { | |
| if (btn.dataset.category === category) { | |
| btn.classList.remove('bg-blue-100', 'text-blue-700'); | |
| btn.classList.add('bg-blue-500', 'text-white'); | |
| } else { | |
| btn.classList.add('bg-blue-100', 'text-blue-700'); | |
| btn.classList.remove('bg-blue-500', 'text-white'); | |
| } | |
| }); | |
| } | |
| // 初始化游戏 | |
| function initGame() { | |
| document.getElementById('game-start').classList.remove('hidden'); | |
| document.getElementById('game-play').classList.add('hidden'); | |
| document.getElementById('game-result').classList.add('hidden'); | |
| // 设置游戏难度按钮事件 | |
| document.querySelectorAll('.game-level').forEach(btn => { | |
| btn.addEventListener('click', function() { | |
| startGame(this.dataset.level); | |
| }); | |
| }); | |
| } | |
| // 开始游戏 | |
| function startGame(level) { | |
| document.getElementById('game-start').classList.add('hidden'); | |
| document.getElementById('game-play').classList.remove('hidden'); | |
| const questions = [...gameQuestions[level]]; | |
| let currentQuestionIndex = 0; | |
| let score = 0; | |
| // 显示第一题 | |
| showQuestion(); | |
| function showQuestion() { | |
| const question = questions[currentQuestionIndex]; | |
| document.getElementById('current-question').textContent = currentQuestionIndex + 1; | |
| document.getElementById('game-score').textContent = score; | |
| if (question.type === 'letter') { | |
| document.getElementById('game-question').textContent = `哪个字母发/${letters.find(l => l.letter === question.question).sound}/的音?`; | |
| } else { | |
| document.getElementById('game-question').textContent = `哪个单词发音是/${question.question}/?`; | |
| } | |
| // 设置播放发音按钮 | |
| document.getElementById('play-sound').onclick = function() { | |
| if (question.type === 'letter') { | |
| speakLetter(question.question.toLowerCase()); | |
| } else { | |
| speakWord(question.question); | |
| } | |
| }; | |
| // 设置选项 | |
| const optionsContainer = document.getElementById('game-options'); | |
| optionsContainer.innerHTML = ''; | |
| question.options.forEach(option => { | |
| const optionBtn = document.createElement('button'); | |
| optionBtn.className = 'px-4 py-3 bg-white border border-gray-300 rounded-lg font-medium hover:bg-gray-100 transition'; | |
| optionBtn.textContent = option; | |
| optionBtn.addEventListener('click', function() { | |
| checkAnswer(option, question.answer); | |
| }); | |
| optionsContainer.appendChild(optionBtn); | |
| }); | |
| } | |
| function checkAnswer(selected, correct) { | |
| const options = document.querySelectorAll('#game-options button'); | |
| options.forEach(opt => { | |
| opt.disabled = true; | |
| if (opt.textContent === correct) { | |
| opt.classList.add('bg-green-100', 'border-green-400'); | |
| } else if (opt.textContent === selected && selected !== correct) { | |
| opt.classList.add('bg-red-100', 'border-red-400'); | |
| } | |
| }); | |
| if (selected === correct) { | |
| score += 20; | |
| document.getElementById('game-score').textContent = score; | |
| showFeedback(true); | |
| } else { | |
| showFeedback(false); | |
| } | |
| // 延迟后进入下一题或结束游戏 | |
| setTimeout(() => { | |
| currentQuestionIndex++; | |
| if (currentQuestionIndex < questions.length) { | |
| showQuestion(); | |
| } else { | |
| endGame(score, level); | |
| } | |
| }, 1500); | |
| } | |
| function showFeedback(isCorrect) { | |
| const feedback = document.createElement('div'); | |
| feedback.className = `fixed top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 text-6xl z-50 ${isCorrect ? 'text-green-500' : 'text-red-500'}`; | |
| feedback.innerHTML = isCorrect ? '<i class="fas fa-check-circle"></i>' : '<i class="fas fa-times-circle"></i>'; | |
| feedback.style.animation = 'bounce 0.5s'; | |
| document.body.appendChild(feedback); | |
| if (isCorrect) { | |
| createConfetti(); | |
| } | |
| setTimeout(() => { | |
| feedback.remove(); | |
| }, 1000); | |
| } | |
| } | |
| // 结束游戏 | |
| function endGame(score, level) { | |
| document.getElementById('game-play').classList.add('hidden'); | |
| const resultSection = document.getElementById('game-result'); | |
| resultSection.classList.remove('hidden'); | |
| document.getElementById('final-score').textContent = score; | |
| // 更新游戏进度 | |
| if (score > userProgress.games[level]) { | |
| userProgress.games[level] = score; | |
| saveProgress(); | |
| } | |
| // 设置结果显示 | |
| const icon = document.getElementById('result-icon'); | |
| const title = document.getElementById('result-title'); | |
| const message = document.getElementById('result-message'); | |
| if (score >= 80) { | |
| icon.className = 'text-6xl mb-4 text-green-500'; | |
| icon.innerHTML = '<i class="fas fa-trophy"></i>'; | |
| title.textContent = '太棒了!'; | |
| title.className = 'text-2xl font-bold mb-2 text-green-600'; | |
| message.textContent = '你是一个拼读小专家!继续保持!'; | |
| } else if (score >= 50) { | |
| icon.className = 'text-6xl mb-4 text-yellow-500'; | |
| icon.innerHTML = '<i class="fas fa-star"></i>'; | |
| title.textContent = '做得不错!'; | |
| title.className = 'text-2xl font-bold mb-2 text-yellow-600'; | |
| message.textContent = '你已经掌握了很多,再多练习会更好!'; | |
| } else { | |
| icon.className = 'text-6xl mb-4 text-red-500'; | |
| icon.innerHTML = '<i class="fas fa-heart"></i>'; | |
| title.textContent = '继续加油!'; | |
| title.className = 'text-2xl font-bold mb-2 text-red-600'; | |
| message.textContent = '不要灰心,多练习字母和单词发音会进步很快!'; | |
| } | |
| // 设置再玩一次按钮 | |
| document.getElementById('play-again').onclick = function() { | |
| initGame(); | |
| }; | |
| } | |
| // 创建彩色纸屑效果 | |
| function createConfetti() { | |
| const colors = ['#f00', '#0f0', '#00f', '#ff0', '#f0f', '#0ff']; | |
| for (let i = 0; i < 50; i++) { | |
| const confetti = document.createElement('div'); | |
| confetti.className = 'confetti'; | |
| confetti.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)]; | |
| confetti.style.left = `${Math.random() * 100}%`; | |
| confetti.style.animation = `confetti-fall ${Math.random() * 3 + 2}s linear forwards`; | |
| confetti.style.animationDelay = `${Math.random() * 0.5}s`; | |
| confetti.style.transform = `rotate(${Math.random() * 360}deg)`; | |
| document.body.appendChild(confetti); | |
| setTimeout(() => { | |
| confetti.remove(); | |
| }, 5000); | |
| } | |
| } | |
| // 发音功能 | |
| function speakLetter(letter) { | |
| const utterance = new SpeechSynthesisUtterance(letter); | |
| utterance.lang = 'en-US'; | |
| utterance.rate = 0.8; | |
| speechSynthesis.speak(utterance); | |
| } | |
| function speakWord(word) { | |
| const utterance = new SpeechSynthesisUtterance(word); | |
| utterance.lang = 'en-US'; | |
| utterance.rate = 0.7; | |
| speechSynthesis.speak(utterance); | |
| } | |
| // 标签切换 | |
| function setupTabs() { | |
| document.getElementById('letters-tab').addEventListener('click', function() { | |
| document.getElementById('letters-section').classList.remove('hidden'); | |
| document.getElementById('words-section').classList.add('hidden'); | |
| document.getElementById('game-section').classList.add('hidden'); | |
| this.classList.remove('bg-blue-200', 'text-blue-700'); | |
| this.classList.add('bg-blue-500', 'text-white'); | |
| document.getElementById('words-tab').classList.add('bg-blue-200', 'text-blue-700'); | |
| document.getElementById('words-tab').classList.remove('bg-blue-500', 'text-white'); | |
| document.getElementById('game-tab').classList.add('bg-blue-200', 'text-blue-700'); | |
| document.getElementById('game-tab').classList.remove('bg-blue-500', 'text-white'); | |
| }); | |
| document.getElementById('words-tab').addEventListener('click', function() { | |
| document.getElementById('letters-section').classList.add('hidden'); | |
| document.getElementById('words-section').classList.remove('hidden'); | |
| document.getElementById('game-section').classList.add('hidden'); | |
| this.classList.remove('bg-blue-200', 'text-blue-700'); | |
| this.classList.add('bg-blue-500', 'text-white'); | |
| document.getElementById('letters-tab').classList.add('bg-blue-200', 'text-blue-700'); | |
| document.getElementById('letters-tab').classList.remove('bg-blue-500', 'text-white'); | |
| document.getElementById('game-tab').classList.add('bg-blue-200', 'text-blue-700'); | |
| document.getElementById('game-tab').classList.remove('bg-blue-500', 'text-white'); | |
| initWords(); | |
| }); | |
| document.getElementById('game-tab').addEventListener('click', function() { | |
| document.getElementById('letters-section').classList.add('hidden'); | |
| document.getElementById('words-section').classList.add('hidden'); | |
| document.getElementById('game-section').classList.remove('hidden'); | |
| this.classList.remove('bg-blue-200', 'text-blue-700'); | |
| this.classList.add('bg-blue-500', 'text-white'); | |
| document.getElementById('letters-tab').classList.add('bg-blue-200', 'text-blue-700'); | |
| document.getElementById('letters-tab').classList.remove('bg-blue-500', 'text-white'); | |
| document.getElementById('words-tab').classList.add('bg-blue-200', 'text-blue-700'); | |
| document.getElementById('words-tab').classList.remove('bg-blue-500', 'text-white'); | |
| initGame(); | |
| }); | |
| } | |
| // 初始化单词分类按钮 | |
| function setupWordCategories() { | |
| document.querySelectorAll('.word-category').forEach(btn => { | |
| btn.addEventListener('click', function() { | |
| initWords(this.dataset.category); | |
| }); | |
| }); | |
| } | |
| // 关闭模态框 | |
| function setupModal() { | |
| document.getElementById('close-modal').addEventListener('click', function() { | |
| document.getElementById('pronunciation-modal').classList.add('hidden'); | |
| }); | |
| } | |
| // 页面加载完成后初始化 | |
| document.addEventListener('DOMContentLoaded', function() { | |
| loadProgress(); | |
| initLetters(); | |
| setupTabs(); | |
| setupWordCategories(); | |
| setupModal(); | |
| // 默认显示字母部分 | |
| document.getElementById('letters-tab').click(); | |
| }); | |
| </script> | |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=echo3700/natural-spell-game" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |