您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# 原生JS面向对象如何实现打字小游戏
## 一、前言
在Web开发中,JavaScript作为核心语言,其面向对象编程(OOP)能力常被忽视。本文将使用原生JS面向对象技术,从零开始构建一个完整的打字小游戏。通过这个项目,您将掌握:
1. ES6类(class)的运用
2. 游戏状态管理
3. DOM操作优化
4. 动画与定时器控制
5. 键盘事件处理
## 二、项目结构与设计
### 2.1 游戏核心模块
```javascript
class TypingGame {
constructor(config) {
// 初始化游戏配置
this.difficulty = config.difficulty || 'normal';
this.timeLimit = config.timeLimit || 60;
this.currentScore = 0;
this.isPlaying = false;
this.timer = null;
this.wordsPool = [];
}
// 其他方法...
}
┌───────────────────┐ ┌───────────────────┐
│ TypingGame │ │ WordItem │
├───────────────────┤ ├───────────────────┤
│ - difficulty │ │ - word │
│ - timeLimit │ │ - speed │
│ - currentScore │ │ - position │
│ - isPlaying │ │ - element │
│ - timer │ ├───────────────────┤
│ - wordsPool │ │ + move() │
├───────────────────┤ │ + createElement() │
│ + startGame() │ └───────────────────┘
│ + endGame() │
│ + updateScore() │
│ + generateWord() │
└───────────────────┘
class WordItem {
constructor(word, options) {
this.word = word;
this.speed = options.speed || 2;
this.position = { x: 0, y: 0 };
this.element = null;
this.init();
}
init() {
this.createElement();
this.setInitialPosition();
}
createElement() {
const wordEl = document.createElement('div');
wordEl.className = 'word-item';
wordEl.textContent = this.word;
document.getElementById('game-area').appendChild(wordEl);
this.element = wordEl;
}
setInitialPosition() {
const gameArea = document.getElementById('game-area');
this.position = {
x: Math.random() * (gameArea.offsetWidth - 200),
y: 0
};
this.updatePosition();
}
move() {
this.position.y += this.speed;
this.updatePosition();
return this.position.y > document.getElementById('game-area').offsetHeight;
}
updatePosition() {
this.element.style.transform = `translate(${this.position.x}px, ${this.position.y}px)`;
}
}
class TypingGame {
// ...constructor...
startGame() {
if (this.isPlaying) return;
this.isPlaying = true;
this.currentScore = 0;
this.updateScoreDisplay();
// 初始化单词池
this.initWordsPool();
// 启动游戏循环
this.gameLoop();
// 设置倒计时
this.startTimer();
// 绑定键盘事件
this.bindEvents();
}
gameLoop() {
if (!this.isPlaying) return;
// 随机生成新单词
if (Math.random() < 0.03) {
this.generateWord();
}
// 移动所有单词
this.wordsPool.forEach((word, index) => {
if (word.move()) {
// 单词超出底部边界
word.element.remove();
this.wordsPool.splice(index, 1);
this.updateScore(-10); // 扣分
}
});
requestAnimationFrame(() => this.gameLoop());
}
generateWord() {
const words = ['JavaScript', 'TypeScript', 'React', 'Vue', 'Angular',
'Node.js', 'Webpack', 'ES6', 'Promise', 'Async'];
const word = words[Math.floor(Math.random() * words.length)];
const speed = this.difficulty === 'hard' ? 3 :
this.difficulty === 'normal' ? 2 : 1;
const newWord = new WordItem(word, { speed });
this.wordsPool.push(newWord);
}
handleInput(inputWord) {
let found = false;
this.wordsPool.forEach((word, index) => {
if (word.word === inputWord) {
word.element.remove();
this.wordsPool.splice(index, 1);
this.updateScore(inputWord.length * 2); // 按长度计分
found = true;
}
});
return found;
}
}
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>JS打字游戏</title>
<style>
#game-container {
width: 800px;
height: 500px;
margin: 0 auto;
position: relative;
border: 2px solid #333;
overflow: hidden;
}
#game-area {
width: 100%;
height: 100%;
background-color: #f0f0f0;
}
#game-ui {
position: absolute;
top: 10px;
left: 10px;
z-index: 100;
}
.word-item {
position: absolute;
font-size: 24px;
color: #333;
white-space: nowrap;
transition: transform 0.1s linear;
}
#input-area {
margin-top: 20px;
text-align: center;
}
#word-input {
padding: 8px;
font-size: 16px;
}
</style>
</head>
<body>
<div id="game-container">
<div id="game-ui">
<div>分数: <span id="score">0</span></div>
<div>时间: <span id="time">60</span>秒</div>
</div>
<div id="game-area"></div>
</div>
<div id="input-area">
<input type="text" id="word-input" placeholder="输入看到的单词...">
</div>
<script src="typing-game.js"></script>
</body>
</html>
// typing-game.js
class WordItem {
constructor(word, options = {}) {
this.word = word;
this.speed = options.speed || 2;
this.position = { x: 0, y: 0 };
this.element = null;
this.init();
}
init() {
this.createElement();
this.setInitialPosition();
}
createElement() {
const wordEl = document.createElement('div');
wordEl.className = 'word-item';
wordEl.textContent = this.word;
document.getElementById('game-area').appendChild(wordEl);
this.element = wordEl;
}
setInitialPosition() {
const gameArea = document.getElementById('game-area');
this.position = {
x: Math.random() * (gameArea.offsetWidth - 200),
y: 0
};
this.updatePosition();
}
move() {
this.position.y += this.speed;
this.updatePosition();
return this.position.y > document.getElementById('game-area').offsetHeight;
}
updatePosition() {
this.element.style.transform = `translate(${this.position.x}px, ${this.position.y}px)`;
}
}
class TypingGame {
constructor(config) {
this.config = {
difficulty: 'normal',
timeLimit: 60,
...config
};
this.currentScore = 0;
this.isPlaying = false;
this.timer = null;
this.wordsPool = [];
this.inputWord = '';
this.init();
}
init() {
this.bindEvents();
}
startGame() {
if (this.isPlaying) return;
this.isPlaying = true;
this.currentScore = 0;
this.updateScoreDisplay();
// 清空现有单词
this.clearWords();
// 启动游戏循环
this.gameLoop();
// 设置倒计时
this.startTimer();
}
endGame() {
this.isPlaying = false;
clearInterval(this.timer);
this.timer = null;
this.clearWords();
alert(`游戏结束! 最终得分: ${this.currentScore}`);
}
clearWords() {
this.wordsPool.forEach(word => word.element.remove());
this.wordsPool = [];
}
gameLoop() {
if (!this.isPlaying) return;
// 随机生成新单词
if (Math.random() < this.getSpawnRate()) {
this.generateWord();
}
// 移动所有单词
this.wordsPool.forEach((word, index) => {
if (word.move()) {
// 单词超出底部边界
word.element.remove();
this.wordsPool.splice(index, 1);
this.updateScore(-10); // 扣分
}
});
requestAnimationFrame(() => this.gameLoop());
}
getSpawnRate() {
switch (this.config.difficulty) {
case 'easy': return 0.02;
case 'normal': return 0.03;
case 'hard': return 0.05;
default: return 0.03;
}
}
generateWord() {
const words = this.getWordList();
const word = words[Math.floor(Math.random() * words.length)];
const speed = this.getWordSpeed();
const newWord = new WordItem(word, { speed });
this.wordsPool.push(newWord);
}
getWordList() {
return [
'function', 'variable', 'constant', 'object', 'array',
'string', 'number', 'boolean', 'null', 'undefined',
'class', 'constructor', 'method', 'property', 'inheritance',
'encapsulation', 'polymorphism', 'abstraction', 'interface',
'prototype', 'closure', 'callback', 'promise', 'async',
'await', 'module', 'import', 'export', 'spread',
'destructuring', 'arrow', 'template', 'literal', 'generator',
'iterator', 'symbol', 'proxy', 'reflect', 'set', 'map'
];
}
getWordSpeed() {
switch (this.config.difficulty) {
case 'easy': return 1;
case 'normal': return 2;
case 'hard': return 3;
default: return 2;
}
}
startTimer() {
let timeLeft = this.config.timeLimit;
document.getElementById('time').textContent = timeLeft;
this.timer = setInterval(() => {
timeLeft--;
document.getElementById('time').textContent = timeLeft;
if (timeLeft <= 0) {
this.endGame();
}
}, 1000);
}
updateScore(points) {
this.currentScore += points;
if (this.currentScore < 0) this.currentScore = 0;
this.updateScoreDisplay();
}
updateScoreDisplay() {
document.getElementById('score').textContent = this.currentScore;
}
bindEvents() {
const inputEl = document.getElementById('word-input');
inputEl.addEventListener('keydown', (e) => {
if (e.key === 'Enter') {
this.handleInput(inputEl.value.trim());
inputEl.value = '';
}
});
// 开始游戏按钮
document.getElementById('start-btn')?.addEventListener('click', () => {
this.startGame();
inputEl.focus();
});
}
handleInput(inputWord) {
if (!this.isPlaying || !inputWord) return;
let found = false;
// 从后往前查找,避免splice影响索引
for (let i = this.wordsPool.length - 1; i >= 0; i--) {
const word = this.wordsPool[i];
if (word.word === inputWord) {
word.element.remove();
this.wordsPool.splice(i, 1);
this.updateScore(inputWord.length * 2); // 按长度计分
found = true;
break; // 只匹配第一个找到的单词
}
}
if (!found) {
this.updateScore(-5); // 输入错误扣分
}
}
}
// 初始化游戏
const game = new TypingGame({
difficulty: 'normal',
timeLimit: 60
});
// 暴露全局变量便于测试
window.game = game;
通过这个打字游戏项目,我们实践了以下面向对象编程原则:
原生JS面向对象开发不仅能构建复杂应用,还能帮助开发者深入理解JavaScript语言特性。这种开发模式在大型项目中尤其重要,能显著提高代码的可维护性和可扩展性。 “`
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。