[Phaser3]イベントに関するTips

2022-3-3

目次

イベントについて

Phaserに於けるイベントとは、プレイヤーによる操作や時間の経過などで発生するアクションの事です。
例えば、キーの押下、シーンの移り変わり、ゲームオブジェクト同士の衝突、など様々なアクションがイベントとして定義されています。ゲーム開発者はそのイベントの発火を検知するコードを書く事で、特定のイベントに対応した処理を仕込むことができます。
また、独自イベントを定義して任意のタイミングで発火させる事も可能です。

基本

イベントを扱う為には、Phaser.Events.EventEmitterというクラス(以下、EventEmitter)を参照する必要があります。

Phaserでは、シーンやゲームオブジェクト、果てはKeyboard Pluginなど多くのクラスでこのEventEmitterを参照する事ができます。

以下は、EventEmitterを参照するための基本的な形になります。

// シーンのEventEmitter
this.events;
// ゲームオブジェクトのEventEmitter
this.player;
// キーボードプラグインのEventEmitter
this.input.keyboard;

シーンではEventEmitterをeventsというプロパティに包含しているので、そこから参照しています。一方で、ゲームオブジェクト、Keyboard PluginはEventEmitterを継承しているため、自身への参照がそのままEventEmitterへの参照となります。

そのクラスがEventEmitterを包含しているか、或いは継承しているか、はドキュメントを見て判断する事になります。

使い方

イベントリスナーを登録する

EventEmitterのon()メソッドを使います。

this.events.on(イベント名, コールバック関数, コンテキスト);

第一引数には、検知したいイベント名、第二引数には実行したいコールバック関数、第三引数にはコールバック関数の属するオブジェクト(コンテキスト)を渡します。

例として、キーボードのイベントを扱ったコードを置いておきます。

例:いづれかのキーが押された事を検知し、hadleKeydown()を呼ぶ

this.input.keyboard.on('keydown', this.handleKeydown, this);

イベント名には文字列、もしくは定数を渡します。

// 下記二つは同じ

// 文字列(タイポに注意)
this.input.keyboard.on('keydown', this.handleKeydown, this);
// 定数(補完の効く環境だと一番確実。しかし、そのまま使うと長い)
this.input.keyboard.on(Phaser.Input.Keyboard.Events.ANY_KEY_DOWN, this.handleKeydown, this);

また、シーンでは以下のようになります。

例:create()が実行された事を検知し、onCreate()を呼ぶ。

// 下記二つは同じ

// 文字列(タイポに注意)
this.events.on('create', this.onCreate, this);
// 定数(補完の効く環境だと一番確実。しかし、そのまま使うと長い)
this.events.on(Phaser.Scenes.Events.CREATE, this.onCreate, this)

Phaserに定義されているイベント名は以下で確認する事ができます。

ドキュメント - イベント一覧

独自イベントを扱う

Phaserに定義されていないイベント名をEventEmitterのon()に渡すと、それが独自イベントとなります。

// イベントを登録
this.events.on('sayHello', this.hello, this);

Phaserに定義されていないイベントなので、EventEmitterのemit()で発火させます。

// イベントを発火
this.events.emit('sayHello');

任意で第二引数にコールバック関数に渡す値を設定できます。

// コールバック関数に'hello'という文字列を渡す
this.events.emit('sayHello', 'hello');,

EventEmitterをもっと詳しく

ドキュメントに載っているメソッドの簡単な説明です。

イベントリスナーを登録する

// 一つ目
this.events.on(イベント名, コールバック関数, コンテキスト);
// 二つ目
this.events.addListener(イベント名, コールバック関数, コンテキスト);

記事中ではon()を使っていましたが、エイリアスなのでどちらを使っても同じです。

一度しか呼ばれないイベントリスナーを登録する

this.events.once(イベント名, コールバック関数, コンテキスト);

イベントの発火

this.events.emit(イベント名);

イベントリスナーを取得する

this.events.listeners(イベント名);

引数に渡したイベントに登録したイベントイスナーが配列で返ります。

イベント名の一覧を取得する

this.events.eventNames();

イベントリスナーが登録されているイベントの名前が配列で返ります。

イベントリスナーの件数を取得する

this.events.listenerCount(イベント名);

引数に渡したイベントに登録されたイベントリスナーの件数が返ります。

イベントリスナーを削除する

// 一つ目
this.events.off(イベント名, コールバック関数, コンテキスト, 一度しか呼ばれないか否か);
// 二つ目
this.events.removeListener(イベント名, コールバック関数, コンテキスト, 一度しか呼ばれないか否か);

第一引数だけの場合、そのイベントに登録したイベントリスナーを全て削除します。
第二引数以降は任意引数で、特定のイベントリスナーだけ削除したい場合に指定します。
エイリアスなのでどちらを使っても同じです。

イベントに登録したイベントリスナーを全て削除するのであれば、以下でも同様の事ができます。

this.events.removeAllListeners(イベント名);

イベントリスナーを全削除する

// 一つ目
this.events.destroy();
// 二つ目
this.events.shutdown();

エイリアスなのでどちらを使っても同じです。

removeAllListeners()は引数がない場合、上記二つと同等の動きをします。

this.events.removeAllListeners();