小游戏实例
通过一个简单的动画游戏实例,展示动画原理、前端实现和后台数据交互的综合运用。
游戏设计
目标
点击移动的方块得分
规则
在限定时间内获得尽可能高的分数
动画
方块移动、点击效果、分数动画
交互
鼠标点击、键盘控制、实时反馈
游戏实现
<!-- 游戏HTML结构 -->
<div id="gameContainer">
<div id="scoreBoard">得分: <span id="score">0</span></div>
<div id="timer">时间: <span id="time">30</span>s</div>
<canvas id="gameCanvas" width="800" height="500"></canvas>
<button id="startBtn">开始游戏</button>
</div>
// 游戏JavaScript实现
class AnimationGame {
constructor() {
this.canvas = document.getElementById('gameCanvas');
this.ctx = this.canvas.getContext('2d');
this.scoreElement = document.getElementById('score');
this.timeElement = document.getElementById('time');
this.startBtn = document.getElementById('startBtn');
this.score = 0;
this.timeLeft = 30;
this.gameActive = false;
this.targets = [];
this.initEventListeners();
}
initEventListeners() {
this.startBtn.addEventListener('click', () => this.startGame());
this.canvas.addEventListener('click', (e) => this.handleCanvasClick(e));
}
startGame() {
this.score = 0;
this.timeLeft = 30;
this.gameActive = true;
this.targets = [];
this.startBtn.textContent = '游戏中...';
this.startBtn.disabled = true;
// 开始游戏循环
this.gameLoop();
// 开始倒计时
this.startTimer();
// 定期生成目标
this.targetGenerator = setInterval(() => {
if (this.gameActive) {
this.generateTarget();
}
}, 1000);
}
startTimer() {
this.timer = setInterval(() => {
this.timeLeft--;
this.timeElement.textContent = this.timeLeft;
if (this.timeLeft <= 0) {
this.endGame();
}
}, 1000);
}
generateTarget() {
const target = {
x: Math.random() * (this.canvas.width - 60) + 30,
y: Math.random() * (this.canvas.height - 60) + 30,
size: Math.random() * 30 + 30, // 30-60像素
color: this.getRandomColor(),
creationTime: Date.now(),
lifeTime: 3000 // 3秒后消失
};
this.targets.push(target);
}
getRandomColor() {
const colors = ['#EF4444', '#3B82F6', '#10B981', '#F59E0B', '#8B5CF6'];
return colors[Math.floor(Math.random() * colors.length)];
}
handleCanvasClick(event) {
if (!this.gameActive) return;
const rect = this.canvas.getBoundingClientRect();
const x = event.clientX - rect.left;
const y = event.clientY - rect.top;
// 检查是否点击到目标
for (let i = this.targets.length - 1; i >= 0; i--) {
const target = this.targets[i];
const distance = Math.sqrt(
Math.pow(x - target.x, 2) + Math.pow(y - target.y, 2)
);
if (distance <= target.size / 2) {
// 点击成功
this.score += 10;
this.scoreElement.textContent = this.score;
// 添加点击爆炸效果
this.addExplosionEffect(target.x, target.y, target.color);
// 移除目标
this.targets.splice(i, 1);
break;
}
}
}
addExplosionEffect(x, y, color) {
// 可以在这里添加粒子爆炸效果
console.log(`爆炸效果在 (${x}, ${y}) 位置,颜色 ${color}`);
}
gameLoop() {
if (!this.gameActive) return;
// 清除画布
this.ctx.fillStyle = '#F8FAFC';
this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
// 更新并绘制目标
const currentTime = Date.now();
for (let i = this.targets.length - 1; i >= 0; i--) {
const target = this.targets[i];
// 检查目标是否超时
if (currentTime - target.creationTime > target.lifeTime) {
this.targets.splice(i, 1);
continue;
}
// 绘制目标
this.ctx.beginPath();
this.ctx.arc(target.x, target.y, target.size / 2, 0, 2 * Math.PI);
this.ctx.fillStyle = target.color;
this.ctx.fill();
// 添加脉冲动画效果
const pulse = Math.sin(currentTime / 200) * 0.2 + 0.8;
this.ctx.strokeStyle = 'rgba(255, 255, 255, ' + pulse + ' )';
this.ctx.lineWidth = 2;
this.ctx.stroke();
}
// 继续游戏循环
requestAnimationFrame(() => this.gameLoop());
}
endGame() {
this.gameActive = false;
clearInterval(this.targetGenerator);
clearInterval(this.timer);
alert(`游戏结束!您的得分是: ${this.score}`);
this.startBtn.textContent = '重新开始';
this.startBtn.disabled = false;
}
}
// 初始化游戏
window.addEventListener('load', () => {
new AnimationGame();
});
游戏特色
| 特性 | 实现方式 | 效果 |
|---|---|---|
| 动态目标 | 随机位置生成,定时消失 | 增加游戏挑战性 |
| 脉冲动画 | 正弦函数控制描边透明度 | 吸引玩家注意力 |
| 实时反馈 | 点击检测,分数更新 | 增强互动体验 |
| 时间限制 | 倒计时机制 | 增加紧迫感 |