動畫和補間

這是 第 14 步,共 16 步,來自 Gamedev Phaser 教程。我們將探索如何在遊戲實現 Phaser 動畫和補間,使遊戲看起來更有趣、更生動。這將帶來更好的、更具娛樂性的體驗。

動畫

在 Phaser 中,動畫涉及從外部資源獲取精靈表,然後按順序顯示精靈。例如,我們將讓球在碰到東西時晃動。

首先,下載精靈表並將其儲存在你的 /img 目錄中。

接下來,我們將載入精靈表——將以下行放在你的 preload() 方法的底部

js
this.load.spritesheet("wobble", "img/wobble.png", {
  frameWidth: 20,
  frameHeight: 20,
});

與其載入單個球影像,不如載入整個精靈表——一個包含不同影像的集合。我們將按順序顯示精靈以創造動畫的錯覺。spritesheet() 方法的額外引數決定了給定精靈表文件中每個單獨幀的寬度和高度,告訴程式如何將其分割以獲取單個幀。

載入動畫

接下來,進入你的 create() 方法,找到載入和配置球精靈的程式碼塊,並在其下方放入對 anims.create 的呼叫,如下所示

js
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() 內的第一行,如下所示

js
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() 方法(以 ballpaddle 作為引數),並在呼叫時播放晃動動畫。將以下方法新增到 hitBrick() 方法的上方

js
class ExampleScene extends Phaser.Scene {
  // ...
  hitPaddle(ball, paddle) {
    this.ball.anims.play("wobble");
  }
  // ...
}

每次球擊中擋板時都會播放動畫。如果你覺得這樣可以讓遊戲看起來更好,也可以將 anims.play() 呼叫放在 hitBrick() 方法內部。

補間

動畫按順序播放外部精靈,而補間則平滑地動畫化遊戲世界中物件的屬性,例如寬度或不透明度。

讓我們向遊戲中新增一個補間,使磚塊在被球擊中時平滑消失。轉到你的 hitBrick() 方法,找到你的 brick.destroy(); 行,並用以下程式碼替換它

js
const destroyTween = this.tweens.add({
  targets: brick,
  ease: "Linear",
  repeat: 0,
  duration: 200,
  props: {
    scaleX: 0,
    scaleY: 0,
  },
  onComplete() {
    brick.destroy();
  },
});
destroyTween.play();

讓我們一步步來,這樣你就能明白髮生了什麼

  1. 在定義新補間時,你必須指定 targets 的哪個屬性將被補間——在我們的例子中,不是在磚塊被球擊中時立即隱藏它們,而是將它們的寬度和高度縮放到零,這樣它們就會很好地消失。為了達到這個目的,我們使用 tweens.add() 方法,指定 brick 作為 targets,並在 props 物件中指定 scaleXscaleY 屬性進行補間。
  2. 我們可以設定的其他屬性是 ease,它定義要使用的緩動函式(在本例中為 Linear),repeat,它定義補間應重複的次數(0 表示不重複),以及 duration,這是補間完成所需的時間(以毫秒為單位)。
  3. 我們還將新增可選的 onComplete 事件處理程式,它定義了一個在補間完成時執行的函式。
  4. 最後要做的是使用 play() 方法立即啟動補間。

Compare your code

這是您到目前為止應該看到的效果,即時執行。要檢視其原始碼,請單擊“播放”按鈕。

後續步驟

動畫和補間看起來很棒,但我們還可以為遊戲新增更多內容——在下一節中,我們將研究處理 按鈕 輸入。