新属性
我们需要一个属性来存储表示游戏当前是否正在进行的布尔值,还需要另一个属性来表示按钮。将以下代码行添加到其他属性定义的下方:
class ExampleScene extends Phaser.Scene {
// ... 之前的属性定义 ...
playing = false;
startButton;
// ... 类的其余部分 ...
}
加载按钮精灵表
我们可以用加载球的摆动动画时相同的方式加载按钮精灵表。将以下代码添加到 preload() 方法的底部:
this.load.spritesheet("button", "img/button.png", {
frameWidth: 120,
frameHeight: 40,
});
单个按钮帧宽 120 像素,高 40 像素。
你还需要获取按钮精灵表,并将其保存到你的 /img 目录中。
将按钮添加到游戏中
可以使用 add.sprite 方法将新按钮添加到游戏中。将以下代码行添加到 create() 方法的底部:
this.startButton = this.add.sprite(
this.scale.width * 0.5,
this.scale.height * 0.5,
"button",
0,
);
除了我们传给其他 add.sprite 调用的参数(例如添加球和球板时使用的参数)之外,这一次还会传入帧编号,也就是这里的 0。这表示精灵表的第一帧会用作按钮的初始外观。
为了让按钮响应鼠标点击等各种输入,我们需要在前面的 add.sprite 调用之后立即添加以下代码行:
this.startButton.setInteractive();
this.startButton.on(
"pointerover",
() => {
this.startButton.setFrame(1);
},
this,
);
this.startButton.on(
"pointerdown",
() => {
this.startButton.setFrame(2);
},
this,
);
this.startButton.on(
"pointerout",
() => {
this.startButton.setFrame(0);
},
this,
);
this.startButton.on(
"pointerup",
() => {
this.startGame();
},
this,
);
首先,我们在按钮上调用 setInteractive,让它能够响应指针事件。然后,我们为按钮添加四个事件监听器:
pointerover:当指针位于按钮上方时,将按钮的帧更改为1,也就是精灵表的第二帧。pointerdown:当按钮被按下时,将按钮的帧更改为2,也就是精灵表的第三帧。pointerout:当指针移出按钮时,将按钮的帧改回0,也就是精灵表的第一帧。pointerup:当按钮被释放时,调用startGame方法来开始游戏。
现在,我们需要定义上面代码引用的 startGame() 方法:
class ExampleScene extends Phaser.Scene {
// ...
startGame() {
this.startButton.destroy();
this.ball.body.setVelocity(150, -150);
this.playing = true;
}
}
当按钮被按下时,我们移除按钮,设置球的初始速度,并将 playing 属性设置为 true。
本节最后一步,回到你的 create 方法,找到 this.ball.body.setVelocity(150, -150); 这一行并删除它。我们只希望球在按钮被按下时移动,而不是在那之前移动!
在游戏开始前保持球板静止
现在的效果已经符合预期,但游戏尚未开始时仍然可以移动球板,这看起来有点奇怪。为了阻止这种情况,我们可以利用 playing 属性,让球板只有在游戏开始后才能移动。为此,请像下面这样调整 update() 方法:
class ExampleScene extends Phaser.Scene {
// ...
update() {
// ...
if (this.playing) {
this.paddle.x = this.input.x || this.scale.width * 0.5;
}
// ...
}
// ...
}
这样一来,在所有内容都加载和准备完毕之后、真正开始游戏之前,球板都无法移动。
比较你的代码
以下是你目前应该得到的结果,可以实时运行。若要查看其源代码,请点击“运行”按钮。
下一步
在本系列文章中我们要做的最后一件事是,为球从球板上弹开的方式添加一些随机性,让游戏玩法更加有趣。