建造砖块区域

这是 第 9 步,共 16 步,来自 Gamedev Phaser 教程。让我们来探索如何使用循环创建一个砖块组并将其显示在屏幕上。建造砖块区域比在屏幕上添加单个对象要复杂一些,尽管与纯 JavaScript 相比,在 Phaser 中仍然更容易。

新属性

首先,在您之前的属性定义下方添加新的 bricks 属性。

js
class ExampleScene extends Phaser.Scene {
  // ... previous property definitions ...
  bricks;
  // ... rest of the class ...
}

bricks 属性将用于创建一个砖块组,这样可以方便地一次管理多个砖块。

渲染砖块图像

接下来,让我们加载砖块的图像—在其他 load.image() 调用下方添加以下调用。

js
class ExampleScene extends Phaser.Scene {
  // ...
  preload() {
    // ...
    this.load.image("brick", "img/brick.png");
  }
  // ...
}

您还需要 获取砖块图像 并将其保存在您的 /img 目录中。

绘制砖块

我们将把绘制砖块的所有代码放在一个名为 initBricks 的方法中,以将其与其余代码分开。在 create() 方法的末尾调用 initBricks

js
class ExampleScene extends Phaser.Scene {
  // ...
  create() {
    // ...
    this.initBricks();
  }
  // ...
}

现在来处理方法本身。在 ExampleScene 类的末尾,也就是在闭合花括号 } 之前,添加 initBricks 方法,如下所示。首先,我们添加 bricksLayout 对象,因为它很快就会派上用场。

js
class ExampleScene extends Phaser.Scene {
  // ...
  initBricks() {
    const bricksLayout = {
      width: 50,
      height: 20,
      count: {
        row: 3,
        col: 7,
      },
      offset: {
        top: 50,
        left: 60,
      },
      padding: 10,
    };
  }
}

这个 bricksLayout 包含了我们所需的所有信息:单个砖块的宽度和高度、屏幕上显示的砖块的行数和列数、顶部和左侧的偏移量(开始绘制砖块的画布位置)以及每行和每列砖块之间的间距。

现在,让我们开始创建砖块本身—首先,添加一个空的组来容纳砖块,方法是在 initBricks() 方法的底部添加以下行。

js
this.bricks = this.add.group();

我们可以循环遍历行和列,在每次迭代中创建一个新的砖块—在上一行代码下方添加以下嵌套循环。

js
for (let c = 0; c < bricksLayout.count.col; c++) {
  for (let r = 0; r < bricksLayout.count.row; r++) {
    // create new brick and add it to the group
  }
}

这样,我们将创建所需数量的砖块,并将它们全部包含在一个组中。现在我们需要在嵌套循环结构中添加一些代码来绘制每个砖块。将内容填充如下。

js
for (let c = 0; c < bricksLayout.count.col; c++) {
  for (let r = 0; r < bricksLayout.count.row; r++) {
    const brickX = 0;
    const brickY = 0;

    const newBrick = this.add.sprite(brickX, brickY, "brick");
    this.physics.add.existing(newBrick);
    newBrick.body.setImmovable(true);
    this.bricks.add(newBrick);
  }
}

这里我们通过循环遍历行和列来创建新的砖块并将它们放置在屏幕上。新创建的砖块已启用 Arcade 物理引擎,其身体被设置为不可移动(因此在被球击中时不会移动),然后被添加到组中。

目前的问题是我们把所有砖块都画在了一个地方,坐标是 (0,0)。我们需要做的是在每个砖块自己的 x 和 y 位置绘制它。如下更新 brickXbrickY 行。

js
const brickX =
  c * (bricksLayout.width + bricksLayout.padding) + bricksLayout.offset.left;
const brickY =
  r * (bricksLayout.height + bricksLayout.padding) + bricksLayout.offset.top;

每个 brickX 位置的计算方式是 bricksLayout.width 加上 bricksLayout.padding,乘以列号 c,再加上 bricksLayout.offset.leftbrickY 的逻辑是相同的,只是它使用了行号 rbricksLayout.heightbricksLayout.offset.top 的值。现在每个砖块都可以放置在其正确的位置,砖块之间有间距,并从画布的左边缘和顶边缘偏移绘制。

此时如果重新加载 index.html,您应该会看到砖块已在屏幕上打印出来,并且彼此之间的距离均匀。

Compare your code

这是您到目前为止应该看到的效果,实时运行。要查看其源代码,请单击“播放”按钮。

后续步骤

但还有些东西缺失。球会穿过砖块而不会停止—我们需要 proper 碰撞检测