【Phaser3】部分的に画面を揺らす方法

Phaser3 で 部分的に画面を揺らす方法 技術ネタ

ゲームでは画面を揺らすことは多々あるかと思います。

Phaser3 で画面全体を揺らす場合は、Phaser.Cameras を使えばできますが、一部分のみ揺らす方法がわからず悩みました。
その時の解決方法について紹介したいと思います。

環境情報
本説明は、以下の環境で行っております。

  • Phaser3 : v3.16.2
  • TypeScript : 3.4.5


一部分のみ揺らす方法

結論としては、Phaser.Cameras を使わずに、Container + Tweens で揺らすことにしました。

具体的な方法は、揺らしたいものを Container に登録し、後は、Tweens に揺らす動きを登録するだけです。

実際のソースコードで説明した方が解りやすいと思いますので、以下のサンプルソースを参照してください。

サンプルソース

このサンプルの画面構成は、上にヘッダー、下にボディがあり、揺らす対象はボディ部分のみとなります。
画面をクリックすると、ヘッダは揺れず、ボディ部分のみ揺れます。

module MyScene {
  export class Scene extends Phaser.Scene {
    private container!: Phaser.GameObjects.Container;

    private create() {
      this.container = this.add.container(0, 0);

      // ヘッダ枠表示
      this.add
        .graphics()
        .lineStyle(10, 0x7fbfff)
        .strokeRect(10, 10, this.game.context.canvas.width - 20, 50);

      let bodyGraphics: Phaser.GameObjects.Graphics = this.add.graphics();

      // ボディ枠表示
      bodyGraphics
        .lineStyle(10, 0xff7f7f)
        .strokeRect(
          10,
          70,
          this.game.context.canvas.width - 20,
          this.game.context.canvas.height - 90
        );
      // ボディに文字表示
      let text: Phaser.GameObjects.Text = this.add.text(
        100,
        100,
        "あいうえお\nかきくけこ",
        {
          fontFamily: "Arial Black",
          fontSize: 30,
          color: "#000000",
          fontStyle: "bold"
        }
      );
      // コンテナに登録
      this.container.add(bodyGraphics);
      this.container.add(text);

      // クリックイベント登録
      this.input.on("pointerdown", () => {
        this.shake();
      });
    }

    private shake() {
      // 現在の位置取得
      let currentX: number = this.container.x;
      let currentY: number = this.container.y;
      let move: number = 10;
      // タイムライン定義
      let timelineConfig: Array<Object> = [];
      for (let i: number = 0; i < 3; i++) {
        timelineConfig.push({
          targets: this.container,
          x: currentX - move,
          y: currentY - move,
          ease: "Power1",
          duration: 30
        });
        timelineConfig.push({
          targets: this.container,
          x: currentX + move,
          y: currentY + move,
          ease: "Power1",
          duration: 30
        });
      }
      timelineConfig.push({
        targets: this.container,
        x: currentX,
        y: currentY,
        ease: "Power1",
        duration: 30
      });
      // Tweens登録
      let timeline = this.tweens.timeline({
        tweens: timelineConfig
      });
    }
  }
}

参考

参考までに、 Phaser.Cameras を使って画面全体を揺らす方法も載せておきます。

module MyScene {
  export class Scene extends Phaser.Scene {
    private create() {
      // ヘッダ枠表示
      this.add
        .graphics()
        .lineStyle(10, 0x7fbfff)
        .strokeRect(10, 10, this.game.context.canvas.width - 20, 50);

      // ボディ枠表示
      this.add
        .graphics()
        .lineStyle(10, 0xff7f7f)
        .strokeRect(
          10,
          70,
          this.game.context.canvas.width - 20,
          this.game.context.canvas.height - 90
        );
      // ボディに文字表示
      let text: Phaser.GameObjects.Text = this.add.text(
        100,
        100,
        "あいうえお\nかきくけこ",
        {
          fontFamily: "Arial Black",
          fontSize: 30,
          color: "#000000",
          fontStyle: "bold"
        }
      );
      // クリックイベント登録
      this.input.on("pointerdown", () => {
        // 画面を揺らす
        this.cameras.main.shake(300);
      });
    }
  }
}

最後に

Phaser3 を使うと簡単にブラウザゲームが作成できます。
同じ悩みがある方がいたら、参考にしていただければと思います。