返回

终于有了飞机大战的纯js实现方式

前端

在前面的学习中,我们基本掌握了常用的 API 和绘画技巧。现在通过实现一个小游戏,来深入了解画布在项目中如何使用。

游戏基本介绍

用户有一艘宇宙飞船,可以用箭头键左右移动,用空格键开火。屏幕顶部的敌人会不断向下移动,玩家需要用子弹将其击落。

游戏实现

  1. 创建画布

首先,我们需要创建一个画布元素。我们可以使用 HTML 的 <canvas> 标签来创建画布。

<canvas id="canvas" width="600" height="400"></canvas>
  1. 获取画布上下文

接下来,我们需要获取画布的上下文。上下文对象允许我们操作画布的内容。

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
  1. 绘制背景

接下来,我们需要绘制游戏背景。我们可以使用 ctx.fillStylectx.fillRect() 方法来绘制矩形。

ctx.fillStyle = '#000';
ctx.fillRect(0, 0, canvas.width, canvas.height);
  1. 创建飞船

接下来,我们需要创建飞船。我们可以使用 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();
  1. 填充飞船

接下来,我们需要填充飞船。我们可以使用 ctx.fillStylectx.fill() 方法来填充飞船。

ctx.fillStyle = '#fff';
ctx.fill();
  1. 创建敌人

接下来,我们需要创建敌人。我们可以使用 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();
  1. 填充敌人

接下来,我们需要填充敌人。我们可以使用 ctx.fillStylectx.fill() 方法来填充敌人。

ctx.fillStyle = '#f00';
ctx.fill();
  1. 移动飞船

接下来,我们需要移动飞船。我们可以使用 addEventListener() 方法来监听键盘事件。

addEventListener('keydown', (e) => {
  switch (e.key) {
    case 'ArrowLeft':
      player.x -= 10;
      break;
    case 'ArrowRight':
      player.x += 10;
      break;
    case ' ':
      player.shoot();
      break;
  }
});
  1. 移动敌人

接下来,我们需要移动敌人。我们可以使用 setInterval() 方法来定时移动敌人。

setInterval(() => {
  enemies.forEach((enemy) => {
    enemy.y += 10;
  });
}, 100);
  1. 碰撞检测

接下来,我们需要检测飞船和敌人之间的碰撞。我们可以使用 ctx.isPointInPath() 方法来检测碰撞。

if (ctx.isPointInPath(player.x, player.y, enemy.path)) {
  // 发生碰撞
}
  1. 游戏循环

最后,我们需要创建一个游戏循环来不断更新游戏画面。

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实现飞机大战游戏的基本步骤。