终于有了飞机大战的纯js实现方式
2023-11-14 18:35:44
在前面的学习中,我们基本掌握了常用的 API 和绘画技巧。现在通过实现一个小游戏,来深入了解画布在项目中如何使用。
游戏基本介绍
用户有一艘宇宙飞船,可以用箭头键左右移动,用空格键开火。屏幕顶部的敌人会不断向下移动,玩家需要用子弹将其击落。
游戏实现
- 创建画布
首先,我们需要创建一个画布元素。我们可以使用 HTML 的 <canvas>
标签来创建画布。
<canvas id="canvas" width="600" height="400"></canvas>
- 获取画布上下文
接下来,我们需要获取画布的上下文。上下文对象允许我们操作画布的内容。
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
- 绘制背景
接下来,我们需要绘制游戏背景。我们可以使用 ctx.fillStyle
和 ctx.fillRect()
方法来绘制矩形。
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, canvas.width, canvas.height);
- 创建飞船
接下来,我们需要创建飞船。我们可以使用 ctx.beginPath()
、ctx.moveTo()
、ctx.lineTo()
和 ctx.closePath()
方法来绘制飞船的形状。
ctx.beginPath();
ctx.moveTo(canvas.width / 2, canvas.height - 50);
ctx.lineTo(canvas.width / 2 - 20, canvas.height - 70);
ctx.lineTo(canvas.width / 2 + 20, canvas.height - 70);
ctx.closePath();
- 填充飞船
接下来,我们需要填充飞船。我们可以使用 ctx.fillStyle
和 ctx.fill()
方法来填充飞船。
ctx.fillStyle = '#fff';
ctx.fill();
- 创建敌人
接下来,我们需要创建敌人。我们可以使用 ctx.beginPath()
、ctx.moveTo()
、ctx.lineTo()
和 ctx.closePath()
方法来绘制敌人的形状。
ctx.beginPath();
ctx.moveTo(Math.random() * canvas.width, 0);
ctx.lineTo(Math.random() * canvas.width, canvas.height / 2);
ctx.lineTo(Math.random() * canvas.width, canvas.height);
ctx.closePath();
- 填充敌人
接下来,我们需要填充敌人。我们可以使用 ctx.fillStyle
和 ctx.fill()
方法来填充敌人。
ctx.fillStyle = '#f00';
ctx.fill();
- 移动飞船
接下来,我们需要移动飞船。我们可以使用 addEventListener()
方法来监听键盘事件。
addEventListener('keydown', (e) => {
switch (e.key) {
case 'ArrowLeft':
player.x -= 10;
break;
case 'ArrowRight':
player.x += 10;
break;
case ' ':
player.shoot();
break;
}
});
- 移动敌人
接下来,我们需要移动敌人。我们可以使用 setInterval()
方法来定时移动敌人。
setInterval(() => {
enemies.forEach((enemy) => {
enemy.y += 10;
});
}, 100);
- 碰撞检测
接下来,我们需要检测飞船和敌人之间的碰撞。我们可以使用 ctx.isPointInPath()
方法来检测碰撞。
if (ctx.isPointInPath(player.x, player.y, enemy.path)) {
// 发生碰撞
}
- 游戏循环
最后,我们需要创建一个游戏循环来不断更新游戏画面。
function gameLoop() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 绘制背景
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 移动飞船
player.move();
// 移动敌人
enemies.forEach((enemy) => {
enemy.move();
});
// 检测碰撞
enemies.forEach((enemy) => {
if (ctx.isPointInPath(player.x, player.y, enemy.path)) {
// 发生碰撞
}
});
// 绘制飞船
ctx.fillStyle = '#fff';
ctx.fill();
// 绘制敌人
enemies.forEach((enemy) => {
ctx.fillStyle = '#f00';
ctx.fill();
});
// 请求下一次动画帧
requestAnimationFrame(gameLoop);
}
gameLoop();
以上就是用canvas实现飞机大战游戏的基本步骤。