HTML5 +JavaScript单词游戏
数据字典格式:每行一个 单词 ,单词和解释用空格分隔,如
a art.一(个);每一(个)
ability n.能力;能耐,本领
able a.有能力的;出色的
baby n.婴儿;孩子气的人
back ad.在后;回原处;回
background n.背景,后景,经历
cable n.缆,索;电缆;电报
cafe n.咖啡馆;小餐厅
good a.好的;有本事的
需要注意的是,JavaScript 在浏览器环境中不能像python那样直接读取本地文本文件,这是出于安全考虑,可以将数据字典内容作为 JavaScript 数据直接嵌入到脚本中。
游戏规则:
每次随机从文本中选取一个英语单词,在界面上从左到右移动,随机选出三个单词的解释,和英语单词正确解释,随机放到四个按钮中,这四个按钮放到界面下方。
用户单击带有解释的按钮,界面上英语单词消失,再随机从文本中选取一个新英语单词,进入下一个猜单词过程;若英语单词移动出界面,用户未能单击有正确解释的按钮,表示失败,也将随机从文本中选取一个新英语单词,进入下一个猜单词过程。
有失败和成功计数。
使用HTML5来实现这个单词游戏, 运行界面:
使用面向过程方式实现,游戏源码如下:
<!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代码是面向过程的,下面使用面向对象方式实现。
使用面向对象方式实现,游戏源码如下:
<!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 等。