👽
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. 外部状態管理ライブラリを導入
- 状態管理が複雑になる場合、
Redux
やMobX
などの外部ライブラリを利用するのも選択肢です。 - 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({ type: 'INCREMENT_SCORE', payload: 10 });
}
}
どの方法を選ぶべきか?
-
簡単なゲーム →
this.registry
の使用が最適 -
中規模のゲーム →
Phaser.Events.EventEmitter
を導入 - 大規模で複雑なゲーム → ReduxやMobXといった外部ライブラリの利用を検討
Phaser 3のシンプルさを活かしたい場合は、registry
や EventEmitter
の利用が多くのケースで十分です。また、必要に応じて外部ライブラリを組み合わせることで、拡張性を持たせることもできます。
Discussion