玩家球拍和控制

这是 Phaser 游戏开发教程 的 16 个步骤中的第 7 步。您可以在 Gamedev-Phaser-Content-Kit/demos/lesson07.html 中找到完成本课后代码应有的样子。

我们让球在移动并弹离墙壁,但这很快就变得无聊了——没有互动!我们需要一种方法来引入游戏玩法,因此在本文中,我们将创建一个球拍来四处移动并击打球。

渲染球拍

从框架的角度来看,球拍与球非常相似——我们需要添加一个变量来表示它,加载相关的图像资源,然后进行操作。

加载球拍

首先,在ball变量之后,添加我们将用于游戏的paddle变量

js
let paddle;

然后,在preload函数中,通过添加以下新的load.image()调用来加载paddle图像

js
function preload() {
  // …
  game.load.image("ball", "img/ball.png");
  game.load.image("paddle", "img/paddle.png");
}

添加球拍图形

为了避免忘记,此时您应该从 GitHub 获取 球拍图形,并将其保存到您的/img文件夹中。

使用物理渲染球拍

接下来,我们将通过在create()函数内添加以下add.sprite()调用来初始化我们的球拍——将其添加到底部

js
paddle = game.add.sprite(
  game.world.width * 0.5,
  game.world.height - 5,
  "paddle",
);

我们可以使用world.widthworld.height值将球拍精确地放置在我们想要的位置:game.world.width*0.5将位于屏幕的正中间。在我们的例子中,世界与画布相同,但对于其他类型的游戏,例如横向卷轴游戏,世界会更大,您可以调整它以创建有趣的效果。

如果您此时重新加载您的index.html,您会注意到球拍目前并不完全在中间。为什么?因为计算位置的锚点始终从对象的左上角开始。我们可以将其更改为使锚点位于球拍宽度的中间和高度的底部,以便更容易将其放置在底部边缘。在前面新增的行下面添加以下行

js
paddle.anchor.set(0.5, 1);

球拍现在放置在我们想要的位置。现在,为了使其与球发生碰撞,我们必须为球拍启用物理。继续添加以下新行,同样在create()函数的底部

js
game.physics.enable(paddle, Phaser.Physics.ARCADE);

现在魔法可以开始了——框架可以在每一帧上处理碰撞检测。要启用球拍和球之间的碰撞检测,请将collide()方法添加到update()函数中,如下所示

js
function update() {
  game.physics.arcade.collide(ball, paddle);
}

第一个参数是我们感兴趣的对象之一——球——第二个是另一个对象,球拍。这可以工作,但并非完全按照我们的预期——当球击中球拍时,球拍会从屏幕上掉下来!我们想要的只是球从球拍上弹开,球拍停留在同一个地方。我们可以将球拍的body设置为immovable,这样当球击中它时它就不会移动。为此,请在create()函数的底部添加以下行

js
paddle.body.immovable = true;

现在它按预期工作了。

控制球拍

下一个问题是我们无法移动球拍。为此,我们可以使用系统的默认输入(鼠标或触摸,取决于平台)并将球拍位置设置为input位置。将以下新行添加到update()函数中,如下所示

js
function update() {
  game.physics.arcade.collide(ball, paddle);
  paddle.x = game.input.x;
}

现在在每一帧中,球拍的x位置将根据输入的x位置进行相应调整,但是当我们启动游戏时,球拍的位置不在中间。这是因为输入位置尚未定义。为了解决这个问题,我们可以将默认位置(如果输入位置尚未定义)设置为屏幕的中间。更新前面的行如下所示

js
paddle.x = game.input.x || game.world.width * 0.5;

如果您还没有这样做,请重新加载您的index.html并尝试一下!

放置球

我们的球拍按预期工作,所以让我们将球放在上面。这与放置球拍非常相似——我们需要将其水平放置在屏幕中间,垂直放置在底部,并稍微偏离底部。为了精确地放置它,我们将锚点设置为球的正中间。找到现有的ball = game.add.sprite()行,并将其替换为以下两行

js
ball = game.add.sprite(game.world.width * 0.5, game.world.height - 25, "ball");
ball.anchor.set(0.5);

速度几乎保持不变——我们只是将第二个参数的值从 150 更改为 -150,这样球就会从向上移动而不是向下移动开始游戏。找到现有的ball.body.velocity.set()行并将其更新为以下内容

js
ball.body.velocity.set(150, -150);

现在球将从球拍的正中间开始。

比较您的代码

您可以在下面的实时演示中查看本课的完整代码,并与之交互以更好地理解其工作原理

后续步骤

我们可以移动球拍并让球从上面弹开,但是如果球无论如何都会从屏幕底部弹开,那有什么意义呢?让我们引入失败的可能性——也就是 游戏结束 逻辑。