phaser-core について
phaser-coreは、Phaserゲームの基盤を作るためのスキルです。ゲーム設定、Sceneのライフサイクル、アセット読み込み、Scene間のデータ共有を扱い、新規プロジェクトではPhaser 4.2を対象とし、既存のPhaser 3.90は同じメジャーバージョンを維持するよう案内します。
主な機能
- 01Phaser.GameとSceneの設定
- 02Sceneのライフサイクル構成
- 03ゲームアセットの読み込みと利用
- 04遷移と共有状態の管理
- 05カメラ範囲と追従の設定
活用シーン
- 01Phaserゲームの基盤構築
- 02アセット読み込みやScene遷移の問題解決
- 03複数Scene間でのデータ共有
- 04新規プロジェクトでのPhaserバージョン選定
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ gamedev-skills/ awesome-gamedev-agent-skills --skill phaser-coreインストール後、Claude Code で/phaser-coreを入力して読み込まれたか確認します。
同梱ファイルreferences/scene-flow.md
詳細
Phaser 4 Core
Phaser ゲームの基盤を設定します。Game の設定、Scene のライフサイクル、アセットの読み込み、カメラ、シーン間のデータ受け渡しを扱います。新規プロジェクトでは Phaser 4.2 を対象とします。既存の Phaser 3.90 プロジェクトは、ユーザーから明示的に移行を依頼されない限り、固定されているメジャーバージョンを維持してください。
使用する場面
- Phaser ゲームの開始、
Phaser.Gameの設定、Sceneの構成、preloadでのアセット読み込み、シーン遷移や共有状態の修正に使用します。 - プロジェクトの
package.jsonにphaserが含まれている、またはimport Phaser from 'phaser'を使用しており、コードでpreload()/create()/update()を使用している場合に使用します。
使用しない場面: 移動、速度、コライダー、重力、オーバーラップには phaser-arcade-physics を使用してください。複雑な剛体シミュレーションには Matter 物理演算を使用します(別の領域です)。エンジンをまたぐセーブ/ロードのパターンには save-systems を使用してください。
基本的なワークフロー
- まずインストールされているメジャーバージョンを確認します。
package.jsonとロックファイルを読みます。新規作業では Phaser 4.2 を使用し、Phaser 3 プロジェクトを暗黙のうちに Phaser 4 に書き換えないでください。 - 設定からゲームを作成します。
type: Phaser.AUTO(WebGL、Canvas へのフォールバックあり)、width/height、scene配列を指定してnew Phaser.Game(config)を実行します。最初のシーンと、active: trueを指定したシーンは自動的に開始します。 - 各画面を
Sceneとしてモデル化します。Phaser.Sceneをサブクラス化し、superに一意のkeyを渡して、ライフサイクルinit(data)→preload()→create(data)→update(time, delta)を実装します。 - アセットは
preloadで読み込み、createで使用します。 キューに追加したアセットは、createまで利用できません。ローダーはシーンごとに存在しますが、読み込まれたキャッシュはグローバルです。 - 実行ごとの状態はコンストラクターではなく
init()でリセットします。 シーンのインスタンスは再起動後も再利用されるため、コンストラクターで設定したフィールドには古い値が残ります。 this.scene.start/launch/switch/sleep/wakeで画面を切り替えます。 データはthis.registry(グローバル)または兄弟シーンのイベントエミッターを通じて共有します。- 実行して動作を確認します。 ページを配信して開き、成功と判断する前に、アセットが読み込まれること(Network タブとコンソールを確認)と、シーンが想定どおり切り替わることを確認します。
パターン
1. ゲームの設定と起動(ES モジュール)
// main.js — one Game owns the renderer, loop, cache, and Scene Manager.
import Phaser from 'phaser';
import BootScene from './scenes/BootScene.js';
import PlayScene from './scenes/PlayScene.js';
const config = {
type: Phaser.AUTO, // WebGL if available, else Canvas
width: 800,
height: 600,
backgroundColor: '#1d1d28',
scale: { mode: Phaser.Scale.FIT, autoCenter: Phaser.Scale.CENTER_BOTH },
scene: [BootScene, PlayScene] // BootScene starts first
};
new Phaser.Game(config);
2. 完全なライフサイクルを持つ Scene
// scenes/PlayScene.js
import Phaser from 'phaser';
export default class PlayScene extends Phaser.Scene {
constructor() {
super('play'); // unique scene key
}
init(data) {
// Reset run-specific state HERE so restarts start clean.
this.score = 0;
this.level = data.level ?? 1;
}
preload() {
// Queue downloads. Not usable until create().
this.load.image('player', 'assets/player.png');
this.load.spritesheet('coin', 'assets/coin.png', { frameWidth: 16, frameHeight: 16 });
}
create() {
this.player = this.add.sprite(400, 300, 'player');
this.scoreText = this.add.text(10, 10, 'Score: 0', { fontSize: '20px', color: '#fff' });
this.cursors = this.input.keyboard.createCursorKeys();
}
update(time, delta) {
// delta is milliseconds since last frame; divide by 1000 for seconds.
const speed = 200 * (delta / 1000);
if (this.cursors.left.isDown) this.player.x -= speed;
if (this.cursors.right.isDown) this.player.x += speed;
}
}
3. シーン間のデータとイベント
// The registry is a global DataManager shared by every scene.
this.registry.set('coins', 0); // in any scene
const coins = this.registry.get('coins'); // read anywhere
// React to registry changes (e.g. a HUD scene listening to gameplay):
this.registry.events.on('changedata-coins', (parent, value) => {
this.coinText.setText(`Coins: ${value}`);
});
// Talk directly to another running scene via its event emitter:
const ui = this.scene.get('hud');
ui.events.emit('show-message', 'Level cleared!');
4. シーン遷移(適切な動詞を選ぶ)
this.scene.start('gameover', { score: this.score }); // stop this scene, start target
this.scene.launch('hud'); // run a second scene in parallel (overlay HUD)
this.scene.switch('menu'); // sleep this scene, start/wake target
this.scene.pause(); // freeze updates but keep rendering (modal)
this.scene.sleep(); // stop updating AND rendering, keep state for wake
5. プレイヤーを追従するカメラ
this.cameras.main.setBounds(0, 0, 1600, 1200); // world size
this.cameras.main.startFollow(this.player, true, 0.1, 0.1); // smooth lerp follow
this.cameras.main.setZoom(1.5);
注意点
create/updateでアセットがundefinedになる →preloadでキューに追加し忘れているか、キーが間違っています。ローダーはpreloadとcreateの間に実行されます。- 再起動後に状態が引き継がれる → フィールドをコンストラクターで設定しています。Scene インスタンスは再利用されます。実行状態は
init()でリセットし、shutdown時に配列をクリアしてください。 this.scene.startとthis.scene.launchの違い →startは呼び出し元のシーンを停止し、launchは対象のシーンを呼び出し元と並行して実行します。HUD にstartを使うとゲームが隠れてしまいます。- コールバック内の
thisが正しくない → アロー関数は Scene のthisを保持します。通常のfunctionコールバックでは、コンテキスト引数または.bind(this)が必要です。 - Phaser 2 のチュートリアルが動作しない → Phaser 3 では「States」が「Scenes」に名称変更され、各 Scene はグローバルな Game World ではなく、それぞれ独自のシステム(入力、カメラ、トゥイーン)を持ちます。
- Phaser 4 で Phaser 3 のカスタムパイプラインが動作しない → Phaser 4 ではレンダラーが再構築され、従来の FX/パイプライン拡張ポイントが置き換えられています。カスタムシェーダーとレンダラープラグインは Phaser 4 のガイドに沿って移行し、内部のレンダラーコードを機械的にコピーしないでください。
- 何も描画されない/画面が黒い → キャンバスがマウントされていること、
width/heightが設定されていること、実際にシーンが開始されていることを確認します(game.scene.dump()の出力を確認してください)。
参考資料
- 一連のシーン状態遷移(pause/resume と sleep/wake、stop/start の違い、再起動時の状態に関する不具合、シーンの削除/置換)については、
references/scene-flow.mdを参照してください。
関連スキル
phaser-arcade-physics— 速度、重力、コライダー、オーバーラップ、グループ。input-systems— 再割り当て可能なマルチデバイス入力アーキテクチャ(エンジンに依存しません)。pixijs-rendering/threejs-scene-setup— その他のブラウザー描画スタック。platformer/puzzle— Phaser スキルを組み合わせたジャンル別テンプレート。
コメント
Markdown 対応