动画和补间
这是 第 14 步,共 16 步,来自 Gamedev Phaser 教程。我们将探索如何在游戏实现 Phaser 动画和补间,使游戏看起来更有趣、更生动。这将带来更好的、更具娱乐性的体验。
动画
在 Phaser 中,动画涉及从外部资源获取精灵表,然后按顺序显示精灵。例如,我们将让球在碰到东西时晃动。
首先,下载精灵表并将其保存在你的 /img 目录中。
接下来,我们将加载精灵表——将以下行放在你的 preload() 方法的底部
this.load.spritesheet("wobble", "img/wobble.png", {
frameWidth: 20,
frameHeight: 20,
});
与其加载单个球图像,不如加载整个精灵表——一个包含不同图像的集合。我们将按顺序显示精灵以创造动画的错觉。spritesheet() 方法的额外参数决定了给定精灵表文件中每个单独帧的宽度和高度,告诉程序如何将其分割以获取单个帧。
加载动画
接下来,进入你的 create() 方法,找到加载和配置球精灵的代码块,并在其下方放入对 anims.create 的调用,如下所示
this.ball = this.add.sprite(
this.scale.width * 0.5,
this.scale.height - 25,
"ball",
);
// ...
this.ball.anims.create({
key: "wobble",
frameRate: 24,
frames: this.anims.generateFrameNumbers("wobble", {
frames: [0, 1, 0, 2, 0, 1, 0, 2, 0],
}),
});
要为对象添加动画,我们使用 anims.create() 方法,该方法接收带有以下属性的参数
key:我们为动画选择的名称。frameRate:帧率(单位为 fps)。由于我们将动画以 24fps 运行,并且有 9 帧,所以动画每秒将显示不到三次。frames:一个定义动画期间显示帧的顺序的数组。如果你再次查看wobble.png图像,你会看到有三帧。Phaser 会提取它们并将对它们的引用存储在数组中——位置 0、1 和 2。上面的数组表示我们显示帧 0,然后是 1,然后是 0,以此类推。
当球击中挡板时应用动画
在处理球与挡板之间碰撞的 physics.collide() 方法调用中(update() 内的第一行,见下文),我们可以添加一个额外的参数,该参数指定一个函数,在每次发生碰撞时执行,与 hitBrick() 方法的执行方式相同。更新 update() 内的第一行,如下所示
class ExampleScene extends Phaser.Scene {
// ...
update() {
this.physics.collide(this.ball, this.paddle, (ball, paddle) =>
this.hitPaddle(ball, paddle),
);
this.physics.collide(this.ball, this.bricks, (ball, brick) =>
this.hitBrick(ball, brick),
);
this.paddle.x = this.input.x || this.scale.width * 0.5;
// ...
}
// ...
}
然后,我们可以创建 hitPaddle() 方法(以 ball 和 paddle 作为参数),并在调用时播放晃动动画。将以下方法添加到 hitBrick() 方法的上方
class ExampleScene extends Phaser.Scene {
// ...
hitPaddle(ball, paddle) {
this.ball.anims.play("wobble");
}
// ...
}
每次球击中挡板时都会播放动画。如果你觉得这样可以让游戏看起来更好,也可以将 anims.play() 调用放在 hitBrick() 方法内部。
补间
动画按顺序播放外部精灵,而补间则平滑地动画化游戏世界中对象的属性,例如宽度或不透明度。
让我们向游戏中添加一个补间,使砖块在被球击中时平滑消失。转到你的 hitBrick() 方法,找到你的 brick.destroy(); 行,并用以下代码替换它
const destroyTween = this.tweens.add({
targets: brick,
ease: "Linear",
repeat: 0,
duration: 200,
props: {
scaleX: 0,
scaleY: 0,
},
onComplete() {
brick.destroy();
},
});
destroyTween.play();
让我们一步步来,这样你就能明白发生了什么
- 在定义新补间时,你必须指定
targets的哪个属性将被补间——在我们的例子中,不是在砖块被球击中时立即隐藏它们,而是将它们的宽度和高度缩放到零,这样它们就会很好地消失。为了达到这个目的,我们使用tweens.add()方法,指定brick作为targets,并在props对象中指定scaleX和scaleY属性进行补间。 - 我们可以设置的其他属性是
ease,它定义要使用的缓动函数(在本例中为Linear),repeat,它定义补间应重复的次数(0 表示不重复),以及duration,这是补间完成所需的时间(以毫秒为单位)。 - 我们还将添加可选的
onComplete事件处理程序,它定义了一个在补间完成时执行的函数。 - 最后要做的是使用
play()方法立即启动补间。
Compare your code
这是您到目前为止应该看到的效果,实时运行。要查看其源代码,请单击“播放”按钮。
后续步骤
动画和补间看起来很棒,但我们还可以为游戏添加更多内容——在下一节中,我们将研究处理 按钮 输入。