1. 项目概述与核心价值
这个打地鼠游戏项目是一个典型的Web前端练手项目,非常适合刚掌握HTML+CSS+JavaScript基础的学习者进行实战演练。通过这个项目,开发者可以综合运用DOM操作、事件处理、定时器、动画效果等前端核心技术,同时培养游戏逻辑思维。
我在2015年第一次接触这个项目时,发现它看似简单实则暗藏玄机。一个完整的打地鼠游戏需要考虑:
- 游戏场景的视觉呈现(CSS布局与动画)
- 地鼠随机出现的逻辑控制(JavaScript算法)
- 用户交互的即时响应(事件监听)
- 游戏状态的动态管理(分数计算、难度调整)
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构解析
2.1 HTML结构设计
游戏的主体结构采用语义化HTML5标签:
html复制<div class="game-container">
<header class="game-header">
<h1>打地鼠</h1>
<div class="score-board">
<span>分数:</span>
<span id="score">0</span>
</div>
</header>
<div class="game-field">
<div class="hole" id="hole1"></div>
<div class="hole" id="hole2"></div>
<!-- 更多洞位... -->
</div>
<div class="control-panel">
<button id="start-btn">开始游戏</button>
<select id="level-select">
<option value="easy">简单</option>
<option value="medium">中等</option>
<option value="hard">困难</option>
</select>
</div>
</div>
关键技巧:使用data-*属性存储洞位状态比直接操作className性能更好
2.2 CSS动画实现
地鼠的进出动画采用CSS3 transition实现流畅效果:
css复制.hole {
position: relative;
width: 100px;
height: 100px;
overflow: hidden;
background: url('hole.png') center no-repeat;
}
.mole {
position: absolute;
width: 80px;
height: 80px;
bottom: -80px;
left: 10px;
background: url('mole.png') center no-repeat;
transition: bottom 0.3s ease-out;
cursor: pointer;
}
.mole.up {
bottom: 10px;
}
.mole.hit {
background: url('mole-hit.png') center no-repeat;
}
实测发现:使用transform: translateY()比修改bottom值性能更优
2.3 JavaScript核心逻辑
游戏主控逻辑采用面向对象方式组织:
javascript复制class WhackAMole {
constructor() {
this.score = 0;
this.timeUp = false;
this.lastHole = null;
this.holes = document.querySelectorAll('.hole');
this.scoreBoard = document.querySelector('#score');
this.startButton = document.querySelector('#start-btn');
this.levelSelect = document.querySelector('#level-select');
this.difficulty = {
easy: { delay: 1500, duration: 1000 },
medium: { delay: 1000, duration: 800 },
hard: { delay: 600, duration: 500 }
};
}
startGame() {
this.score = 0;
this.timeUp = false;
this.scoreBoard.textContent = 0;
this.startButton.disabled = true;
const level = this.levelSelect.value;
this.peep(level);
setTimeout(() => {
this.timeUp = true;
this.startButton.disabled = false;
}, 10000); // 10秒游戏时长
}
peep(level) {
if (this.timeUp) return;
const time = this.difficulty[level];
const hole = this.randomHole();
hole.classList.add('up');
setTimeout(() => {
hole.classList.remove('up');
