React 英語單詞消消樂一款專為英語學習設計的互動式記憶游戲

📖 項目簡介

英語單詞消消樂?是一款專為英語學習設計的互動式記憶游戲。通過經典的消消樂玩法,讓用戶在輕松愉快的游戲中掌握英語單詞,提高詞匯量和記憶效果。

🎯 項目目標

  • 讓英語學習變得有趣且高效
  • 通過游戲化方式增強單詞記憶
  • 提供多樣化的單詞庫選擇
  • 支持語音朗讀功能,提升聽說能力

? 核心功能特色

🎮 游戲玩法

  • 經典消消樂模式:點擊英語單詞和對應的中文翻譯來消除
  • 智能匹配系統:自動識別英文-中文配對
  • 實時反饋:匹配成功有消失動畫,失敗有抖動提示
  • 進度追蹤:實時顯示匹配進度和得分

🗣? 語音功能

  • 雙語朗讀:支持英語和中文語音朗讀
  • 智能語音:根據卡片類型自動選擇語言
  • 可調節語速:英語稍慢便于學習,中文正常語速
  • 語音開關:用戶可自由開啟/關閉語音功能

📚 單詞庫系統

  • 多樣化主題:水果、動物、顏色、數字等多個主題
  • 易于擴展:模塊化設計,可輕松添加新單詞庫
  • 實時切換:游戲過程中可隨時切換單詞庫

🎨 用戶體驗

  • 響應式設計:完美適配手機、平板、電腦
  • 精美動畫:流暢的卡片動畫和交互效果
  • 直觀界面:簡潔美觀的 UI 設計
  • 即時反饋:清晰的操作提示和狀態顯示

🛠? 技術棧

  • React.js?– 現代化的用戶界面框架
  • Tailwind CSS?– 實用優先的 CSS 框架
  • JavaScript ES6+?– 現代 JavaScript 語法
  • Web Speech API?– 瀏覽器原生語音合成

全部源碼

import { useState, useEffect } from "react";
import { wordLibraries } from "../data/wordLibraries";export default function WordsGame() {const [currentLibrary, setCurrentLibrary] = useState("fruits");const [gameWords, setGameWords] = useState([]);const [selectedCards, setSelectedCards] = useState([]);const [matchedPairs, setMatchedPairs] = useState([]);const [score, setScore] = useState(0);const [gameComplete, setGameComplete] = useState(false);const [gameStarted, setGameStarted] = useState(false);const [disappearingCards, setDisappearingCards] = useState([]);const [shakingCards, setShakingCards] = useState([]);const [speechSynthesis, setSpeechSynthesis] = useState(null);const [speechEnabled, setSpeechEnabled] = useState(true);// 初始化游戲const initializeGame = () => {const library = wordLibraries[currentLibrary];const allWords = [...library.words];// 隨機選擇10對單詞(20張卡片)const shuffled = allWords.sort(() => Math.random() - 0.5).slice(0, 10);// 創建卡片數組,每對單詞創建兩張卡片const cards = [];shuffled.forEach((word, index) => {cards.push({id: `english-${index}`,type: "english",content: word.english,pairId: index,matched: false,});cards.push({id: `chinese-${index}`,type: "chinese",content: word.chinese,pairId: index,matched: false,});});// 隨機打亂卡片順序const shuffledCards = cards.sort(() => Math.random() - 0.5);setGameWords(shuffledCards);setSelectedCards([]);setMatchedPairs([]);setScore(0);setGameComplete(false);setGameStarted(true);};// 處理卡片點擊const handleCardClick = (card) => {if (card.matched || selectedCards.length >= 2) return;// 朗讀卡片內容speakCardContent(card);const newSelectedCards = [...selectedCards, card];setSelectedCards(newSelectedCards);if (newSelectedCards.length === 2) {const [card1, card2] = newSelectedCards;// 檢查是否匹配if (card1.pairId === card2.pairId && card1.type !== card2.type) {// 匹配成功 - 添加溫和的消失動畫setDisappearingCards([card1.id, card2.id]);setTimeout(() => {setMatchedPairs((prev) => [...prev, card1.pairId]);setScore((prev) => prev + 10);setSelectedCards([]);setDisappearingCards([]);// 檢查游戲是否完成if (matchedPairs.length + 1 === 10) {setGameComplete(true);}}, 400);} else {// 匹配失敗 - 添加抖動動畫和標紅效果setShakingCards([card1.id, card2.id]);setTimeout(() => {setSelectedCards([]);setShakingCards([]); // 動畫結束后復位}, 1000);}}};// 切換單詞庫const changeLibrary = (libraryKey) => {setCurrentLibrary(libraryKey);setGameStarted(false);};// 檢查卡片是否被選中const isCardSelected = (card) => {return selectedCards.some((selected) => selected.id === card.id);};// 檢查卡片是否已匹配const isCardMatched = (card) => {return matchedPairs.includes(card.pairId);};// 檢查卡片是否正在消失const isCardDisappearing = (card) => {return disappearingCards.includes(card.id);};// 檢查卡片是否正在抖動const isCardShaking = (card) => {return shakingCards.includes(card.id);};// 朗讀卡片內容const speakCardContent = (card) => {if (speechEnabled && speechSynthesis && !speechSynthesis.speaking) {const utterance = new SpeechSynthesisUtterance(card.content);// 根據卡片類型設置語言if (card.type === "english") {utterance.lang = "en-US";utterance.rate = 0.8; // 稍微慢一點,便于學習} else {utterance.lang = "zh-CN";utterance.rate = 0.9;}utterance.volume = 0.8;utterance.pitch = 1.0;speechSynthesis.speak(utterance);}};// 測試語音功能const testSpeech = () => {if (speechSynthesis) {const testText = "語音功能測試";const utterance = new SpeechSynthesisUtterance(testText);utterance.lang = "zh-CN";utterance.rate = 0.9;utterance.volume = 0.8;speechSynthesis.speak(utterance);}};useEffect(() => {if (gameStarted) {initializeGame();}}, [currentLibrary]);// 初始化語音合成useEffect(() => {if ("speechSynthesis" in window) {setSpeechSynthesis(window.speechSynthesis);}}, []);return (<div className="min-h-screen bg-gradient-to-br from-blue-50 via-indigo-50 to-purple-50 py-4 px-4"><div className="max-w-6xl mx-auto">{/* 標題和單詞庫選擇 */}<div className="flex flex-col lg:flex-row justify-between items-center mb-4 gap-4"><div className="text-center flex-1"><h1 className="text-xl md:text-2xl lg:text-3xl font-bold text-indigo-700 mb-1 animate-bounce">🎮 英語單詞消消樂</h1><p className="text-xs md:text-sm lg:text-base text-indigo-600 font-medium">點擊英語單詞和對應的中文翻譯來消除吧!</p></div>{/* 單詞庫選擇和語音開關 */}<div className="flex flex-col sm:flex-row items-center gap-3">{/* 語音開關 */}<div className="bg-gradient-to-r from-emerald-100 to-teal-100 rounded-xl shadow-md p-2 md:p-3 border-2 border-emerald-200"><div className="flex items-center space-x-1 md:space-x-2"><span className="text-xs md:text-sm font-bold text-emerald-700">{speechEnabled ? "🔊" : "🔇"}</span><buttononClick={() => setSpeechEnabled(!speechEnabled)}className={`px-2 md:px-3 py-1 text-xs md:text-sm font-bold rounded-lg border-2 transition-all duration-200 cursor-pointer ${speechEnabled? "bg-emerald-500 text-white border-emerald-400": "bg-gray-300 text-gray-600 border-gray-400"}`}>{speechEnabled ? "語音開" : "語音關"}</button><buttononClick={testSpeech}className="px-1 md:px-2 py-1 text-xs font-bold bg-blue-500 text-white rounded border-2 border-blue-400 transition-all duration-200 cursor-pointer hover:bg-blue-600">測試</button></div></div>{/* 單詞庫選擇 */}<div className="bg-gradient-to-r from-indigo-100 to-purple-100 rounded-xl shadow-md p-2 md:p-3 border-2 border-indigo-200"><div className="flex items-center"><span className="text-xs md:text-sm font-bold text-indigo-700 mr-1 md:mr-2">🌈</span><selectvalue={currentLibrary}onChange={(e) => changeLibrary(e.target.value)}className="px-2 md:px-3 py-1 text-xs md:text-sm font-bold text-indigo-700 bg-white rounded-lg border-2 border-indigo-200 shadow-sm focus:outline-none focus:border-purple-400 transition-all duration-200 cursor-pointer">{Object.entries(wordLibraries).map(([key, library]) => (<optionkey={key}value={key}className="text-xs md:text-sm font-bold">{library.name}</option>))}</select></div></div></div></div>{/* 游戲狀態 */}<div className="bg-gradient-to-r from-emerald-100 to-teal-100 rounded-xl shadow-md p-3 mb-4 border-2 border-emerald-200"><div className="flex justify-between items-center mb-3"><div className="text-sm md:text-base font-bold text-emerald-700">🎯 {wordLibraries[currentLibrary].name}</div><div className="text-lg md:text-xl font-bold text-indigo-600">? {score}</div></div>{!gameStarted ? (<buttononClick={initializeGame}className="w-full bg-gradient-to-r from-emerald-500 to-teal-600 hover:from-emerald-600 hover:to-teal-700 text-white font-bold py-2 px-4 rounded-xl text-base md:text-lg shadow-md transform hover:scale-105 transition-all duration-200 border-2 border-emerald-400">🚀 開始游戲</button>) : (<div className="text-center"><div className="text-sm md:text-base text-emerald-600 mb-2 font-bold">🎪 {matchedPairs.length} / 10</div><buttononClick={initializeGame}className="bg-gradient-to-r from-indigo-500 to-purple-600 hover:from-indigo-600 hover:to-purple-700 text-white font-bold py-1 px-3 rounded-lg text-sm md:text-base shadow-md transform hover:scale-105 transition-all duration-200 border-2 border-indigo-400">🔄 重新開始</button></div>)}</div>{/* 游戲完成提示 */}{gameComplete && (<div className="bg-gradient-to-r from-emerald-200 to-indigo-200 border-2 border-emerald-400 text-emerald-800 px-4 py-3 rounded-xl mb-4 text-center shadow-md animate-pulse"><h3 className="text-xl md:text-2xl font-bold mb-2">🎉 恭喜!游戲完成!🎉</h3><p className="text-lg font-bold">最終得分: ? {score} ?</p></div>)}{/* 游戲卡片區域 */}{gameStarted && (<div className="relative"><div className="grid grid-cols-4 sm:grid-cols-5 md:grid-cols-8 lg:grid-cols-10 gap-1 md:gap-2">{gameWords.map((card) => (<divkey={card.id}onClick={() => !isCardMatched(card) && handleCardClick(card)}className={`h-16 sm:h-20 md:h-24 rounded-lg md:rounded-xl shadow-md transition-all duration-300 transform${isCardMatched(card)? "opacity-0 pointer-events-none": "cursor-pointer hover:scale-105 hover:rotate-1"}${isCardDisappearing(card)? "animate-disappear pointer-events-none bg-gradient-to-br from-indigo-300 to-purple-300 border-2 border-indigo-500 shadow-lg": isCardShaking(card)? "animate-shake pointer-events-none bg-gradient-to-br from-red-200 to-pink-200 border-2 border-red-400 shadow-md": isCardSelected(card)? "bg-gradient-to-br from-indigo-200 to-purple-200 border-2 border-indigo-400 shadow-md": "bg-gradient-to-br from-slate-50 to-gray-100 border-2 border-slate-200 hover:border-indigo-400 hover:shadow-md"}`}><div className="flex items-center justify-center h-full p-1 md:p-2 w-full"><spanclassName={`text-xs md:text-sm font-bold text-center word-card-text w-full${card.type === "english"? "text-indigo-700": "text-emerald-700"}`}>{card.content}</span></div></div>))}</div></div>)}{/* 游戲說明 */}<div className="bg-gradient-to-r from-slate-100 to-gray-100 rounded-xl shadow-md p-3 mt-4 border-2 border-slate-200"><h3 className="text-lg font-bold text-slate-700 mb-3 text-center">📖 游戲規則</h3><ul className="text-slate-700 space-y-2 text-sm font-medium"><li className="flex items-center">🎯 點擊英語單詞和對應的中文翻譯來消除</li><li className="flex items-center">👆 每次只能選擇兩張卡片</li><li className="flex items-center">? 匹配成功得10分,匹配失敗不扣分</li><li className="flex items-center">🏆 消除所有卡片即可完成游戲</li><li className="flex items-center">🔄 可以隨時切換不同的單詞庫</li><li className="flex items-center">🔊 點擊卡片時會朗讀內容,可開關語音功能</li></ul></div></div></div>);
}

React 英語單詞消消樂,一款專為英語學習設計的互動式記憶游戲 - 高質量源碼分享平臺-免費下載各類網站源碼與模板及前沿動態資訊

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/87862.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/87862.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/87862.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Qt:QPushButton、QRadioButton、QCheckBox

目錄 一、QPushButton 1.認識QPushButton 2.設置按鈕圖標 3.設置按鈕的快捷鍵 二、QRadioButton 常用的信號 按鈕的分組 三、QCheckBox 一、QPushButton 1.認識QPushButton QPushButton繼承自QWidget&#xff0c;所以在上一篇文章中介紹的QWidget的屬性&#xff0c;理…

docker 無法拉取鏡像解決方法

目錄 我在omv中通過后臺頁面拉取alist鏡像總是失敗&#xff0c;原因千奇百怪 今天再戰終于解決首先&#xff0c;到dockerhub找鏡像和wiki進入docker賬號設置 找到里面提示了登錄操作和密碼命令行中執行后會提示成功之后按需配置代理&#xff0c;同時檢查自己的配置檢查 Docker …

安卓10.0系統修改定制化_____安卓9與安卓10系統文件差異 有關定制選項修改差異

在修改安卓10的rom之前。我們需要對rom有簡單的了解。區分安卓10與安卓9之間的差異。了解不同安卓版本之間系統文件的變化以及權限的區別。對于修改一些定制化選項有很大的輔助作用. 通過博文了解?????? 1??????-----安卓10與安卓9之間文件實例對比 了解差異 …

HTML表單元素全面指南:從基礎到實踐

引言 HTML表單是網頁開發中不可或缺的一部分&#xff0c;它為用戶提供了與網站交互的途徑。無論是簡單的登錄頁面還是復雜的數據提交界面&#xff0c;表單元素都扮演著關鍵角色。本文將詳細介紹各種HTML表單元素及其使用方法。 輸入框(input元素) input元素是最基礎也是最靈…

深度學習的核心理論與技術

理解深度學習的基本原理、核心算法和關鍵技術 深度學習的核心理論與技術前言一、深度學習核心理論1. 神經網絡基礎核心內容練習資源2. 反向傳播與梯度下降核心內容練習資源3. 卷積神經網絡&#xff08;CNN&#xff09;核心內容練習資源4. 循環神經網絡&#xff08;RNN&#xff…

LinkedList 鏈表數據結構實現 (OPENPPP2)

&#x1f50d; LinkedList 鏈表數據結構實現 (OPENPPP2) &#x1f9f1; 1. 數據結構設計 LinkedListNode 結構 #mermaid-svg-XDJqt6cHMKxodJLG {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-XDJqt6cHMKxodJLG .er…

RPC/gRPC入門學習

一、RPC 1.1 RPC概念 RPC Remote Procedure Call, 即遠程過程調用&#xff0c;是一種用于構建分布式系統的理念&#xff0c;在一些資料中被稱為“請求-響應”協議。兩個進程可以位于同一系統中&#xff0c;也可以位于不同的系統中&#xff0c;通過網絡相互連接。 RPC使程…

租車小程序電動車租賃小程序php方案

電動車租賃小程序源碼&#xff0c;開發語言后端php&#xff0c;前端uniapp。四個端&#xff1a;用戶端門店端分銷商端小程序&#xff0c;pc管理后臺。一 用戶端&#xff1a;可以掃門店碼&#xff0c;進入門店詳情頁。也可以通過地圖找車。或者門店列表進入&#xff0c;或者快速…

Python數據分析基礎04:預測性數據分析

相關章節&#xff1a; 《Python數據分析基礎03&#xff1a;探索性數據分析》 《python數據分析基礎02&#xff1a;數據可視化分析》 《Python數據分析基礎01&#xff1a;描述性統計分析》 預測性數據分析&#xff08;Predictive Analytics&#xff09; 的深度解析&#xff0…

PFAE(Pyramidal Frequency Attention Extraction)通過頻域注意力機制提高邊界模糊、遮擋等場景的的檢測能力

在偽裝物體檢測中&#xff0c;現有方法多依賴空間局部特征&#xff0c;難以捕捉全局信息&#xff0c;而 Transformer 類方法計算成本高昂。頻率域特征因具備全局建模能力&#xff0c;可有效抑制背景噪聲、提升偽裝物體語義清晰度&#xff0c;但頻域與空域的頻繁轉換會增加計算復…

AE插件安裝方法

Adobe After Effects簡稱AE&#xff0c;是adobe公司開發的一個視頻剪輯及設計軟件&#xff0c;AE軟件能夠實現對素材的非線性編輯而完成畫面的組接&#xff0c;同時還能對任何一部分進行修改&#xff0c;達到想要的結果。AE含有很多腳本、常用的表達式和插件&#xff0c;做動畫…

舵輪時鐘-STM32-28路PWM--ESP8266-NTP時間

1.STM32--PWM生成STM32不具備如此多的PWM&#xff0c;因此采用軟件定時器的方案實現&#xff1a;使用hal庫實現&#xff1b;main.c#include "main.h"#define close1 500#define open 1500#define close 2500// 定時器中斷配置&#xff08;以TIM2為例&#xff09; voi…

Redis的單線程和多線程(單Worker線程)

Redis的單線程和多線程 Redis6.0之前是單線程的&#xff0c;6.0之后是多線程的&#xff0c;我們先了解6.0版本之前的單線程Redis。但其實無論6.0之前還是6.0之后&#xff0c;redis用于工作的線程也只有一個&#xff0c;所以也可以說redis一直是單線程的。 Redis單線程 Redis 6.…

OSPFv3基礎

文章目錄 OSPFv3基礎OSPFv3的改進OSPFv2 v3相同OSPFv2 v3不同 &#x1f3e1;作者主頁&#xff1a;點擊&#xff01; &#x1f916;Datacom專欄&#xff1a;點擊&#xff01; ??創作時間&#xff1a;2025年07月07日22點31分 OSPFv3基礎 OSPFv3協議號依然為89&#xff0c;在I…

前端篇——HTML知識點體系

目錄 一、基礎結構與文本 1. 文檔基礎 2. 文本元素 二、多媒體元素 1. 圖像 2. 音頻 3. 視頻 三、列表系統 1. 無序列表 2. 有序列表 3. 定義列表 四、表格系統 1. 表格結構 2. 合并單元格 五、表單系統 1. 輸入控件 2. 表單元素 3. 高級表單特性 六、布局系…

產品需求管理文檔中,需求模塊是怎么界定的

產品需求文檔中&#xff0c;需求模塊的界定方式主要包括&#xff1a;1、基于業務流程的功能劃分、2、按用戶角色使用場景分類、3、根據系統架構與技術邊界拆解、4、對數據實體和功能點進行組合聚類、5、結合未來演進節奏設置獨立迭代單元。 其中&#xff0c;“基于業務流程的功…

國內免代理免費使用Gemini大模型實戰

文章目錄 一、免費申請Gemini API密鑰二、使用openai-gemini1、在github上找到openai-gemini2、將openai-gemini部署到Netlify3、在Cherry Studio中配置和使用gemini的模型1&#xff09;在Cherry Studio中配置gemini API2&#xff09;在Cherry Studio中使用gemini 的模型 4、在…

day46-tomcat-java業務部署

1. ?選型1.1. &#x1f3af;中間件java web中間件說明tomcat組件&#xff0c;功能多jetty精簡&#xff0c;功能少一些......weblogic使用oracle數據庫配合weblogic(商業)國產&#xff1a;東方通(TongWEB)1.2. &#x1f4cc;jdkjdk選型說明jdk(oracle jdk)商業版&#xff0c;jd…

[netty5: HttpServerCodec HttpClientCodec]-源碼分析

在閱讀該篇文章之前&#xff0c;推薦先閱讀以下內容&#xff1a; [netty5: ChannelHandler & ChannelHandlerAdapter]-源碼解析[netty5: HttpObjectEncoder & HttpObjectDecoder]-源碼解析 HttpServerCodec HttpServerCodec 是一個 Netty 編解碼器&#xff0c;結合 …

華為OD機試 2025B卷 - 數組組成的最小數字(C++PythonJAVAJSC語言)

2025B卷目錄點擊查看: 華為OD機試2025B卷真題題庫目錄|機考題庫 + 算法考點詳解 2025B卷 100分題型 最新華為OD機試 真題目錄:點擊查看目錄 華為OD面試真題精選:點擊立即查看 2025華為od 機試2025B卷-華為機考OD2025年B卷 題目描述 給定一個整型數組,請從該數組中選…