HTML5+JavaScript单词游戏

HTML5 +JavaScript单词游戏

数据字典格式:每行一个 单词 ,单词和解释用空格分隔,如

a art.一(个);每一(个)

ability n.能力;能耐,本领

able a.有能力的;出色的

baby n.婴儿;孩子气的人

back ad.在后;回原处;回

background n.背景,后景,经历

cable n.缆,索;电缆;电报

cafe n.咖啡馆;小餐厅

good a.好的;有本事的

需要注意的是,JavaScript 在浏览器环境中不能像python那样直接读取本地文本文件,这是出于安全考虑,可以将数据字典内容作为 JavaScript 数据直接嵌入到脚本中。

游戏规则:

每次随机从文本中选取一个英语单词,在界面上从左到右移动,随机选出三个单词的解释,和英语单词正确解释,随机放到四个按钮中,这四个按钮放到界面下方。

用户单击带有解释的按钮,界面上英语单词消失,再随机从文本中选取一个新英语单词,进入下一个猜单词过程;若英语单词移动出界面,用户未能单击有正确解释的按钮,表示失败,也将随机从文本中选取一个新英语单词,进入下一个猜单词过程。

有失败和成功计数。

使用HTML5来实现这个单词游戏, 运行界面:

使用面向过程方式实现,游戏源码如下:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>单词游戏</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            display: flex;
            flex-direction: column;
            align-items: center;
            padding: 20px;
        }
        #gameCanvas {
            border: 1px solid black;
        }
        #score {
            align-self: flex-end;
            margin-bottom: 10px;
        }
        #buttons {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 10px;
            margin-top: 20px;
        }
        button {
            width: 180px;
            height: 40px;
            font-size: 14px;
        }
    </style>
</head>
<body>
    <div id="score">成功: 0 失败: 0</div>
    <canvas id="gameCanvas" width="400" height="200"></canvas>
    <div id="buttons"></div>

    <script>
 // 字典数据
        const dictionaryData = `
a art.一(个);每一(个)
ability n.能力;能耐,本领
able a.有能力的;出色的
baby n.婴儿;孩子气的人
back ad.在后;回原处;回
background n.背景,后景,经历
cable n.缆,索;电缆;电报
cafe n.咖啡馆;小餐厅
good a.好的;有本事的
        `;

        const canvas = document.getElementById('gameCanvas');
        const ctx = canvas.getContext('2d');
        const scoreElement = document.getElementById('score');
        const buttonsContainer = document.getElementById('buttons');

        let dictionary = {};
        let currentWord = "";
        let currentDefinition = "";
        let options = [];
        let successCount = 0;
        let failCount = 0;
        let wordX = -100;
        let moveSpeed = 1; // 新增:移动速度控制
        let lastTime = 0;  // 新增:用于控制动画帧率

	function loadDictionary() {
            const lines = dictionaryData.trim().split('\n');
            lines.forEach(line => {
                const [word, definition] = line.trim().split(' ', 2);
                dictionary[word] = definition;
            });
        }

        function chooseNewWord() {
            const words = Object.keys(dictionary);
            currentWord = words[Math.floor(Math.random() * words.length)];
            currentDefinition = dictionary[currentWord];
            options = [currentDefinition];
            while (options.length < 4) {
                const randomDef = dictionary[words[Math.floor(Math.random() * words.length)]];
                if (!options.includes(randomDef)) {
                    options.push(randomDef);
                }
            }
            options.sort(() => Math.random() - 0.5);
            updateButtons();
            wordX = -100;
        }

        function updateButtons() {
            buttonsContainer.innerHTML = '';
            options.forEach((option, index) => {
                const button = document.createElement('button');
                button.textContent = option.substring(0, 20) + "...";
                button.onclick = () => checkAnswer(index);
                buttonsContainer.appendChild(button);
            });
        }

        function moveWord(currentTime) {
            // 控制帧率,每16ms(约60fps)更新一次
            if (currentTime - lastTime < 16) {
                requestAnimationFrame(moveWord);
                return;
            }
            lastTime = currentTime;

            ctx.clearRect(0, 0, canvas.width, canvas.height);
            ctx.font = '24px Arial';
            ctx.fillText(currentWord, wordX, 100);

            if (wordX > canvas.width) {
                failCount++;
                updateScore();
                chooseNewWord();
            } else {
                wordX += moveSpeed; // 使用moveSpeed控制移动速度
            }

            requestAnimationFrame(moveWord);
        }

        function checkAnswer(index) {
            if (options[index] === currentDefinition) {
                successCount++;
            } else {
                failCount++;
            }
            updateScore();
            chooseNewWord();
        }

        function updateScore() {
            scoreElement.textContent = `成功: ${successCount} 失败: ${failCount}`;
        }

        function init() {
            loadDictionary();
            chooseNewWord();
            requestAnimationFrame(moveWord);
        }

        init();
    </script>
</body>
</html>

你可以通过调整 moveSpeed 的值来改变单词移动的速度。例如:

moveSpeed = 0.5; 会使单词移动得更慢

moveSpeed = 2; 会使单词移动得更快

上面的JavaScript代码是面向过程的,下面使用面向对象方式实现。

使用面向对象方式实现,游戏源码如下:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>单词游戏</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            display: flex;
            flex-direction: column;
            align-items: center;
            padding: 20px;
        }
        #gameCanvas {
            border: 1px solid black;
        }
        #score {
            align-self: flex-end;
            margin-bottom: 10px;
        }
        #buttons {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 10px;
            margin-top: 20px;
        }
        button {
            width: 180px;
            height: 40px;
            font-size: 14px;
        }
    </style>
</head>
<body>
    <div id="score">成功: 0 失败: 0</div>
    <canvas id="gameCanvas" width="400" height="200"></canvas>
    <div id="buttons"></div>

    <script>

 // 字典数据
        const dictionaryData = `
a art.一(个);每一(个)
ability n.能力;能耐,本领
able a.有能力的;出色的
baby n.婴儿;孩子气的人
back ad.在后;回原处;回
background n.背景,后景,经历
cable n.缆,索;电缆;电报
cafe n.咖啡馆;小餐厅
good a.好的;有本事的
        `;

        class WordGame {
            constructor() {
                this.canvas = document.getElementById('gameCanvas');
                this.ctx = this.canvas.getContext('2d');
                this.scoreElement = document.getElementById('score');
                this.buttonsContainer = document.getElementById('buttons');

                this.dictionary = {};
                this.currentWord = "";
                this.currentDefinition = "";
                this.options = [];
                this.successCount = 0;
                this.failCount = 0;
                this.wordX = -100;
                this.moveSpeed = 1;
                this.lastTime = 0;

                this.loadDictionary();
                this.chooseNewWord();
                this.updateButtons();
                requestAnimationFrame(this.moveWord.bind(this));
            }


	    loadDictionary() {
                const lines = dictionaryData.trim().split('\n');
                lines.forEach(line => {
                    const [word, definition] = line.trim().split(' ', 2);
                    this.dictionary[word] = definition;
                });
            }

            chooseNewWord() {
                const words = Object.keys(this.dictionary);
                this.currentWord = words[Math.floor(Math.random() * words.length)];
                this.currentDefinition = this.dictionary[this.currentWord];
                this.options = [this.currentDefinition];
                while (this.options.length < 4) {
                    const randomDef = this.dictionary[words[Math.floor(Math.random() * words.length)]];
                    if (!this.options.includes(randomDef)) {
                        this.options.push(randomDef);
                    }
                }
                this.options.sort(() => Math.random() - 0.5);
                this.wordX = -100;
            }

            updateButtons() {
                this.buttonsContainer.innerHTML = '';
                this.options.forEach((option, index) => {
                    const button = document.createElement('button');
                    button.textContent = option.substring(0, 20) + "...";
                    button.onclick = () => this.checkAnswer(index);
                    this.buttonsContainer.appendChild(button);
                });
            }

            moveWord(currentTime) {
                if (currentTime - this.lastTime < 16) {
                    requestAnimationFrame(this.moveWord.bind(this));
                    return;
                }
                this.lastTime = currentTime;

                this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
                this.ctx.font = '24px Arial';
                this.ctx.fillText(this.currentWord, this.wordX, 100);

                if (this.wordX > this.canvas.width) {
                    this.failCount++;
                    this.updateScore();
                    this.chooseNewWord();
                    this.updateButtons();
                } else {
                    this.wordX += this.moveSpeed;
                }

                requestAnimationFrame(this.moveWord.bind(this));
            }

            checkAnswer(index) {
                if (this.options[index] === this.currentDefinition) {
                    this.successCount++;
                } else {
                    this.failCount++;
                }
                this.updateScore();
                this.chooseNewWord();
                this.updateButtons();
            }

            updateScore() {
                this.scoreElement.textContent = `成功: ${this.successCount} 失败: ${this.failCount}`;
            }
        }

        // 初始化游戏
        new WordGame();
    </script>
</body>
</html>

这个面向对象的实现有以下几个主要特点:

所有游戏逻辑都封装在 WordGame 类中。

类的构造函数 constructor 初始化所有必要的属性和状态,并开始游戏循环。

每个功能都变成了类的方法,如 loadDictionary, chooseNewWord, updateButtons 等。

相关推荐
魏大帅。几秒前
Axios 的 responseType 属性详解及 Blob 与 ArrayBuffer 解析
前端·javascript·ajax
花花鱼7 分钟前
vue3 基于element-plus进行的一个可拖动改变导航与内容区域大小的简单方法
前端·javascript·elementui
k093310 分钟前
sourceTree回滚版本到某次提交
开发语言·前端·javascript
web行路人42 分钟前
React中类组件和函数组件的理解和区别
前端·javascript·react.js·前端框架
番茄小酱00143 分钟前
Expo|ReactNative 中实现扫描二维码功能
javascript·react native·react.js
子非鱼9211 小时前
【Ajax】跨域
javascript·ajax·cors·jsonp
超雄代码狂1 小时前
ajax关于axios库的运用小案例
前端·javascript·ajax
周亚鑫2 小时前
vue3 pdf base64转成文件流打开
前端·javascript·pdf
Footprint_Analytics2 小时前
Footprint Analytics 助力 Sei 游戏生态增长
游戏·web3·区块链
落魄小二2 小时前
el-table 表格索引不展示问题
javascript·vue.js·elementui