Phaser3 Loadingシーン

phaser

Phaser3 Loadingシーン

前回の記事
https://mijinc0.github.io/blog/post/20200821_phaser3_cameraeffects/

概要

loading...って出るシーン欲しくないですか。ほしいですよね。2Dでゲームを作っていると特にオーディオデータなんかは比較的サイズが大きくなりやすいし、もし小さいゲームなら最初にアセットを全部読み込んでしまってキャッシュに貯めておきたいですよね。その間画面が真っ暗のままだとプレイヤーを不安にさせるし、最近だとロード画面中にゲームのTIPS何かを表示するのに使っていたりしますよね。作りましょう。

簡単なLoadingシーン

import * as Phaser from 'phaser';

export class Loading extends Phaser.Scene {
  
  private progressBar: Phaser.GameObjects.Rectangle;

  preload(): void {
    const progressBar = this.add.rectangle(16, 160, 0, 8, 0xffffff);
    this.loadingText = this.add.text(80, 80, 'loading...', {});

    // 進捗バーを更新するイベント
    this.scene.load.on('progress', this._updateBar.bind(this));
    // 一つのファイルの読込が完了したときのイベント
    this.scene.load.on('load', this._loadingSuccessful.bind(this));
    // 全てのファイルのロード処理が完了した時のイベント
    this.scene.load.on('complete', this._complete.bind(this));

    // 以下、ロード処理
    this.load.json(...args);
    this.load.spritesheet(...args);
  }

  private _updateBar(percentage: number): void {
    const maxWidth = 400;

    this.progressBar.width = 400 * percentage;
  }

  /**
   * これはデバッグ用。何をロードしたのか後から確認できたほうが良い。
   */
  private _loadingSuccessful(file: any): void {
    const src = file.src ? file.src : 'unknown/path';
    const key = file.src ? file.key : 'unknown_key';
    console.log(`load asset : ${key} : ${src}`);
  }

  private _complete(): void {
    console.log('loading complete');

    this.cameras.main.fadeOut(500, 0, 0, 0, (camera: Phaser.Cameras.Scene2D.Camera, progress: number) => {
      if (progress === 1) {
        this.scene.start('nextScene');
      }
    });
  }
}

特に説明することは無い。

  1. progressイベントは進捗をパーセンテージ(100% = 1.0)で受け取れるので、進捗に応じて進捗バーを伸ばす
  2. ファイルがロード出来たらコンソールで確認できるようにする
  3. 全てのロードが完了したら目的のシーンに移るようにイベントを仕込んでおく

これだけ。Phaser3ではアセットのキャッシュは全てのシーンから参照可能なので、各シーンのpreloadにそれぞれで必要なアセットを毎回読み込まなくても、最初にローディングシーンを作ってそこで読み込んでしまえば良い。