构建砖块区域
这是 游戏开发 Phaser 教程 的 16 个步骤中的第 **9 步**。您可以在 Gamedev-Phaser-Content-Kit/demos/lesson09.html 中找到完成本课后代码应有的样子。
构建砖块区域比在屏幕上添加单个对象稍微复杂一些,尽管在 Phaser 中比在纯 JavaScript 中更容易。让我们探讨如何使用循环创建一个砖块组并将它们打印到屏幕上。
定义新变量
首先,让我们定义所需的变量 - 在您之前的变量定义下方添加以下内容
let bricks;
let newBrick;
let brickInfo;
bricks
变量将用于创建一个组,newBrick
将是循环每次迭代时添加到组中的一个新对象,而 brickInfo
将存储我们所需的所有数据。
渲染砖块图像
接下来,让我们加载砖块的图像 - 在其他 load.image()
调用下方添加以下内容
function preload() {
// …
game.load.image("brick", "img/brick.png");
}
您还需要从 GitHub 获取砖块图像 并将其保存到您的 /img
目录中。
绘制砖块
我们将把所有用于绘制砖块的代码放在 initBricks
函数中,以将其与其他代码分离。在 create()
函数的末尾添加对 initBricks
的调用
function create() {
// …
initBricks();
}
现在进入函数本身。将 initBricks()
函数添加到我们游戏代码的末尾,就在结束标签 </script>
之前,如下所示。首先,我们包含了 brickInfo
对象,因为它很快就会派上用场
function initBricks() {
brickInfo = {
width: 50,
height: 20,
count: {
row: 3,
col: 7,
},
offset: {
top: 50,
left: 60,
},
padding: 10,
};
}
这个 brickInfo
对象将保存我们所需的所有信息:单个砖块的宽度和高度,我们将在屏幕上看到的砖块行数和列数,顶部和左偏移量(我们在画布上开始绘制砖块的位置)以及每个砖块行和列之间的填充。
现在,让我们开始创建砖块本身 - 首先添加一个空组来容纳砖块,在 initBricks()
函数的底部添加以下行
bricks = game.add.group();
我们可以遍历行和列来创建每次迭代的新砖块 - 在之前代码行的下方添加以下嵌套循环
for (let c = 0; c < brickInfo.count.col; c++) {
for (let r = 0; r < brickInfo.count.row; r++) {
// create new brick and add it to the group
}
}
这样,我们将创建所需数量的砖块,并将它们全部包含在一个组中。现在,我们需要在嵌套循环结构中添加一些代码来绘制每个砖块。按照以下内容填写内容
for (let c = 0; c < brickInfo.count.col; c++) {
for (let r = 0; r < brickInfo.count.row; r++) {
let brickX = 0;
let brickY = 0;
newBrick = game.add.sprite(brickX, brickY, "brick");
game.physics.enable(newBrick, Phaser.Physics.ARCADE);
newBrick.body.immovable = true;
newBrick.anchor.set(0.5);
bricks.add(newBrick);
}
}
在这里,我们遍历行和列以创建新的砖块并将它们放置在屏幕上。新创建的砖块被启用用于 Arcade 物理引擎,其主体被设置为不可移动(因此它在被球击中时不会移动),我们还将锚点设置为居中,并将砖块添加到组中。
目前的问题是,我们把所有的砖块都画在一个地方,坐标为 (0,0)。我们需要做的是在每个砖块的 x 和 y 位置绘制每个砖块。将 brickX
和 brickY
行更新如下
const brickX =
c * (brickInfo.width + brickInfo.padding) + brickInfo.offset.left;
const brickY =
r * (brickInfo.height + brickInfo.padding) + brickInfo.offset.top;
每个 brickX
位置都被计算为 brickInfo.width
加上 brickInfo.padding
,乘以列号 c
,再加上 brickInfo.offset.left
;brickY
的逻辑相同,只是它使用行号 r
、brickInfo.height
和 brickInfo.offset.top
的值。现在,每个砖块都可以放置在正确的位置,每个砖块之间都有填充,并在距画布左边缘和顶边缘的偏移量处绘制。
检查 initBricks() 代码
以下是 initBricks()
函数的完整代码
function initBricks() {
brickInfo = {
width: 50,
height: 20,
count: {
row: 3,
col: 7,
},
offset: {
top: 50,
left: 60,
},
padding: 10,
};
bricks = game.add.group();
for (let c = 0; c < brickInfo.count.col; c++) {
for (let r = 0; r < brickInfo.count.row; r++) {
const brickX =
c * (brickInfo.width + brickInfo.padding) + brickInfo.offset.left;
const brickY =
r * (brickInfo.height + brickInfo.padding) + brickInfo.offset.top;
newBrick = game.add.sprite(brickX, brickY, "brick");
game.physics.enable(newBrick, Phaser.Physics.ARCADE);
newBrick.body.immovable = true;
newBrick.anchor.set(0.5);
bricks.add(newBrick);
}
}
}
如果您此时重新加载 index.html
,您应该会在屏幕上看到绘制的砖块,它们彼此之间相隔均匀。
比较您的代码
您可以在下面的实时演示中查看本课的完成代码,并尝试使用它,以更好地理解它的工作原理