630 文字
3 分
Phaser3で状態管理を実装する

Phaser 3で状態管理を実装するには、アプリケーションの複雑さや要件に応じて、いくつかの方法があります。以下に一般的なアプローチを説明します。


基本的な状態管理の手法#

1. グローバル変数を利用#

  • シンプルな状態管理の方法として、ゲーム全体で共有するグローバル変数を利用することができます。
  • Phaser 3では、this.registry が状態の保存に使用できます。
    • this.registry はシーンからアクセス可能で、ゲーム全体で共有されます。

サンプルコード#

class MainScene extends Phaser.Scene {
constructor() {
super({ key: 'MainScene' });
}
preload() {}
create() {
// 状態の初期化
this.registry.set('score', 0);
this.registry.set('playerHealth', 100);
// 状態の更新
this.registry.set('score', this.registry.get('score') + 10);
console.log('Current Score:', this.registry.get('score'));
// シーン間で状態を引き継ぐ例
this.scene.start('NextScene');
}
}

2. イベントエミッターを活用#

  • 状態の変更や通知を管理するために、PhaserのPhaser.Events.EventEmitterを利用できます。
  • 複数のシーン間で状態変更を通知する場合に便利です。

サンプルコード#

class GameState extends Phaser.Events.EventEmitter {
constructor() {
super();
this.state = {
score: 0,
playerHealth: 100,
};
}
set(key, value) {
this.state[key] = value;
this.emit('stateChanged', this.state);
}
get(key) {
return this.state[key];
}
}
const gameState = new GameState();
class MainScene extends Phaser.Scene {
constructor() {
super({ key: 'MainScene' });
}
create() {
gameState.on('stateChanged', (newState) => {
console.log('State Updated:', newState);
});
// 状態の更新
gameState.set('score', 10);
}
}

3. 外部状態管理ライブラリを導入#

  • 状態管理が複雑になる場合、ReduxMobX などの外部ライブラリを利用するのも選択肢です。
  • Phaser 3と組み合わせて使う場合、ライブラリの管理部分をゲームロジックやUIに統合します。

サンプルコード(Reduxを利用)#

import { createStore } from 'redux';
// 状態の初期値
const initialState = {
score: 0,
playerHealth: 100,
};
// Reducer関数
function gameReducer(state = initialState, action) {
switch (action.type) {
case 'INCREMENT_SCORE':
return { ...state, score: state.score + action.payload };
case 'DECREMENT_HEALTH':
return { ...state, playerHealth: state.playerHealth - action.payload };
default:
return state;
}
}
// Reduxストアの作成
const store = createStore(gameReducer);
class MainScene extends Phaser.Scene {
constructor() {
super({ key: 'MainScene' });
}
create() {
// ストアの変更を監視
store.subscribe(() => {
console.log('State Updated:', store.getState());
});
// ストアの状態を更新
store.dispatch({ , payload: 10 });
}
}

どの方法を選ぶべきか?#

  1. 簡単なゲームthis.registry の使用が最適
  2. 中規模のゲームPhaser.Events.EventEmitter を導入
  3. 大規模で複雑なゲーム → ReduxやMobXといった外部ライブラリの利用を検討

Phaser 3のシンプルさを活かしたい場合は、registryEventEmitter の利用が多くのケースで十分です。また、必要に応じて外部ライブラリを組み合わせることで、拡張性を持たせることもできます。