📜  JavaScript 中的 Flappy Bird 游戏(1)

📅  最后修改于: 2023-12-03 15:31:40.332000             🧑  作者: Mango

JavaScript 中的 Flappy Bird 游戏

Flappy Bird 是一款很受欢迎的小游戏,玩家需要通过点击屏幕使小鸟飞起,同时避开障碍物,尽可能地飞得远。这款游戏也成为了许多开发者使用的案例,展示了如何使用 JavaScript 和 HTML5 来制作游戏。

实现 Flappy Bird 游戏的步骤

要在 JavaScript 中实现 Flappy Bird 游戏,需要完成以下步骤:

  1. 创建画布和游戏元素
  2. 绘制背景和小鸟
  3. 实现点击屏幕小鸟飞起的效果
  4. 实现障碍物的动画效果
  5. 实现碰撞检测
  6. 实现分数统计和显示

下面我们将一步步地介绍如何完成这些步骤。

创建画布和游戏元素

首先,我们需要在 HTML 页面中创建一个画布元素,用来显示游戏界面:

<canvas id="canvas" width="288" height="512"></canvas>

然后,在 JavaScript 中获取该元素,并创建游戏元素的对象:

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');

var bird = {
  x: 50,
  y: 150,
  width: 34,
  height: 24,
  speed: 0,
  gravity: 0.25
};

var pipes = [];

这里我们创建了一个小鸟对象和一个障碍物的数组,用来存储游戏中需要绘制的元素。

绘制背景和小鸟

接下来,我们需要使用 canvasgetContext() 方法获取一个 2D 绘图上下文对象,并使用其提供的 fillRect() 方法来绘制背景和小鸟:

function draw() {
  ctx.fillStyle = '#70c5ce';
  ctx.fillRect(0, 0, canvas.width, canvas.height);

  ctx.fillStyle = '#ffffff';
  ctx.fillRect(bird.x, bird.y, bird.width, bird.height);
}

这里我们定义了一个 draw() 函数,用来绘制背景和小鸟。首先使用 fillRect() 方法绘制一个蓝色的背景,然后用 fillRect() 方法绘制一个白色的小鸟。

实现点击屏幕小鸟飞起的效果

为了实现点击屏幕小鸟飞起的效果,我们需要为画布添加点击事件,在点击事件中改变小鸟的速度:

canvas.addEventListener('click', function() {
  bird.speed = -5;
});

这里我们在画布上添加点击事件,当点击事件触发时,把小鸟的速度设置为 -5

然后,在 draw() 函数中,我们需要更新小鸟的位置:

function draw() {
  ...

  bird.speed += bird.gravity;
  bird.y += bird.speed;
}

这里我们把 speed 属性加上一个重力加速度 gravity,然后把小鸟的 y 坐标加上 speed,实现小鸟自由落体和飞行的效果。

实现障碍物的动画效果

接下来,我们需要实现障碍物的动画效果。首先,我们需要创建障碍物的类:

function Pipe() {
  this.width = 52;
  this.height = 320;
  this.x = canvas.width;
  this.y = randomHeight();
}

function randomHeight() {
  return Math.floor(Math.random() * 200) + 50;
}

这里我们创建了一个 Pipe 类,用来表示障碍物。每个障碍物的宽度都是 52 像素,高度随机生成。我们使用 randomHeight() 方法来生成随机高度。

然后,在 draw() 函数中,我们创建障碍物的对象,并把它们加入到 pipes 数组中:

function draw() {
  ...

  if (frames % 100 === 0) {
    pipes.push(new Pipe());
  }

  for (var i = 0; i < pipes.length; i++) {
    var p = pipes[i];

    ctx.fillStyle = '#20a30f';
    ctx.fillRect(p.x, p.y, p.width, p.height);

    p.x -= 2;
  }
}

这里我们使用 frames 变量来控制障碍物的生成速度和速度,每生成 100 帧,创建一个障碍物的对象,并加入到 pipes 数组中。然后,循环遍历 pipes 数组,绘制每一个障碍物,并把障碍物的 x 坐标减去 2,实现障碍物向左移动的效果。

实现碰撞检测

要实现碰撞检测,我们需要判断小鸟是否触碰到了障碍物。我们可以使用 canvasisPointInPath() 方法来实现这个功能:

function collides(rect, x, y) {
  return x > rect.x && x < rect.x + rect.width &&
         y > rect.y && y < rect.y + rect.height;
}

function checkCollision() {
  for (var i = 0; i < pipes.length; i++) {
    var p = pipes[i];

    if (collides(p, bird.x, bird.y) || collides(p, bird.x + bird.width, bird.y) ||
        collides(p, bird.x, bird.y + bird.height) || collides(p, bird.x + bird.width, bird.y + bird.height)) {
      return true;
    }
  }

  return false;
}

这里我们定义了两个函数,collides()checkCollision()collides() 用来检测一个点是否在一个矩形范围内,然后我们使用 checkCollision() 函数来遍历 pipes 数组,检测小鸟是否和障碍物相撞。

实现分数统计和显示

为了实现分数统计和显示,我们需要定义一个得分的变量,并在小鸟飞过一个障碍物时加一分:

var score = 0;

function updateScore() {
  for (var i = 0; i < pipes.length; i++) {
    var p = pipes[i];

    if (p.x + p.width < bird.x) {
      score++;
    }
  }
}

这里我们在 updateScore() 函数中,遍历 pipes 数组,判断小鸟是否飞过了每一个障碍物。如果飞过了,则将分数加一。

然后,在 draw() 函数中,我们显示分数:

function draw() {
  ...

  ctx.fillStyle = '#fff';
  ctx.font = '24px Helvetica';
  ctx.fillText('Score: ' + score, 10, 30);
}

这里我们使用 fillText() 方法,在画布上显示分数。

完整代码

完整代码如下: