一键导入
dev-phaser-fundamentals
Phaser game configuration, scenes, and lifecycle management
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Phaser game configuration, scenes, and lifecycle management
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | dev-phaser-fundamentals |
| description | Phaser game configuration, scenes, and lifecycle management |
"2D web games made simple – scenes, sprites, and physics."
Use when:
import Phaser from "phaser";
import { MainScene } from "./scenes/MainScene";
const config: Phaser.Types.Core.GameConfig = {
type: Phaser.AUTO,
width: 800,
height: 600,
parent: "game-container",
backgroundColor: "#000000",
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_BOTH,
},
physics: {
default: "arcade",
arcade: {
gravity: { y: 300 },
debug: false,
},
},
scene: [MainScene],
};
new Phaser.Game(config);
// Manual game loop without Phaser
const canvas = document.getElementById("game") as HTMLCanvasElement;
const ctx = canvas.getContext("2d")!;
let playerX = 400;
let playerY = 300;
// Manual asset loading
const playerImg = new Image();
playerImg.src = "assets/player.png";
playerImg.onload = () => {
gameLoop();
};
// Manual game loop
function gameLoop() {
// Clear canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Draw player
ctx.drawImage(playerImg, playerX, playerY);
// Handle input manually
document.addEventListener("keydown", (e) => {
if (e.key === "ArrowLeft") playerX -= 5;
// ... more manual input handling
});
requestAnimationFrame(gameLoop);
}
Problems:
// Phaser handles everything
export class GameScene extends Phaser.Scene {
private player!: Phaser.Physics.Arcade.Sprite;
preload() {
// Built-in asset loading with progress tracking
this.load.image("player", "assets/player.png");
}
create() {
// Physics-enabled sprite
this.player = this.physics.add.sprite(400, 300, "player");
// Built-in input handling
this.cursors = this.input.keyboard!.createCursorKeys();
}
update() {
// Frame-independent movement
if (this.cursors.left!.isDown) {
this.player.setVelocityX(-160);
}
// Built-in physics handles position updates
}
}
const config = {
// Phaser manages the game loop, canvas, rendering
scene: [GameScene],
physics: { default: "arcade" },
};
new Phaser.Game(config);
Benefits:
| Need | Use |
|---|---|
| Basic 2D game | Phaser.AUTO renderer type |
| Physics platformer | Arcade physics with gravity |
| Physics puzzle | Matter physics for realism |
| Responsive layout | Phaser.Scale.FIT with CENTER_BOTH |
| Multiple scenes | Array of scene classes in config |
export class MainScene extends Phaser.Scene {
constructor() {
super({ key: "MainScene" });
}
preload() {
// Load assets before create()
this.load.image("player", "assets/player.png");
this.load.image("background", "assets/bg.png");
}
create() {
// Create game objects
this.add.image(400, 300, "background");
this.player = this.physics.add.sprite(400, 300, "player");
}
update(time: number, delta: number) {
// Game loop (60fps)
// delta = time since last frame in ms
}
}
export class GameScene extends Phaser.Scene {
constructor() {
super({ key: "GameScene", active: false });
}
init(data: { level: number; score: number }) {
// Receive data from previous scene
this.level = data.level || 1;
this.score = data.score || 0;
}
preload() {
// Load level-specific assets
this.load.image(`level${this.level}`, `assets/level${this.level}.png`);
}
create() {
// Setup game objects
this.createPlayer();
this.createEnemies();
}
update(time: number, delta: number) {
this.updatePlayer();
this.updateEnemies();
}
}
const config: Phaser.Types.Core.GameConfig = {
type: Phaser.AUTO,
width: 800,
height: 600,
parent: "game-container",
backgroundColor: "#2d2d2d",
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_BOTH,
width: 800,
height: 600,
},
physics: {
default: "arcade",
arcade: {
gravity: { x: 0, y: 1000 },
debug: false,
},
},
scene: [BootScene, PreloadScene, TitleScene, GameScene, UIScene],
pipeline: { CustomPipeline: CustomPipeline },
};
interface ExtendedGameConfig extends Phaser.Types.Core.GameConfig {
customSettings: {
maxPlayers: number;
gameMode: "deathmatch" | "capture";
};
}
class CustomGame extends Phaser.Game {
constructor(config: ExtendedGameConfig) {
super(config);
this.customSettings = config.customSettings;
}
}
export class MainScene extends Phaser.Scene {
create() {
// Scene transitions
this.scene.start("GameScene", { level: 1 });
// Launch parallel scene (UI overlay)
this.scene.launch("UIScene");
// Pause current scene
this.scene.pause();
// Sleep scene (stops update but keeps rendering)
this.scene.sleep("BackgroundScene");
// Stop and remove scene
this.scene.stop("OldScene");
}
}
❌ DON'T:
create() - use preload()update() - causes GC pressurethis.scene.restart() frequently - expensive operationsuper() in scene constructor✅ DO:
preload() before useupdate()shutdown() methodscale.manager for responsive sizingthis.add.group()export class GameScene extends Phaser.Scene {
private player!: Phaser.Physics.Arcade.Sprite;
private enemies!: Phaser.GameObjects.Group;
private cursors!: Phaser.Types.Input.Keyboard.CursorKeys;
constructor() {
super({ key: "GameScene" });
}
create() {
// Always setup shutdown for cleanup
this.events.once(Phaser.Scenes.Events.SHUTDOWN, this.shutdown, this);
}
shutdown() {
// Clean up listeners
this.input.keyboard!.off("keydown-ESC");
}
update(time: number, delta: number) {
// Use delta for frame-independent movement
const dt = delta / 1000; // Convert to seconds
}
}
const config: Phaser.Types.Core.GameConfig = {
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_BOTH,
width: 800,
height: 600,
},
};
// In scene, get scale info
this.scale.width; // Actual canvas width
this.scale.height; // Actual canvas height
Before completing Phaser setup:
| Issue | Solution |
|---|---|
| Assets not loading | Check preload() runs before create() |
| Physics not working | Verify physics config and body type |
| Scene not updating | Check scene is active: true |
| Canvas size wrong | Configure scale manager |
| Memory leaks | Clean up in shutdown() |
Phaser 3 provides built-in support for loading JSON files containing level data:
// In preload(), load the JSON file
preload() {
// Load individual level files
this.load.json('level001', 'data/levels/level001.json');
// Load level index
this.load.json('levels', 'data/levels.json');
}
// In create(), access the loaded data
create() {
// Get level index
const levelsIndex = this.cache.json.get('levels');
console.log('Available levels:', levelsIndex.levels);
// Get specific level data
const level001Data = this.cache.json.get('level001');
console.log('Level 1 pigs:', level001Data.pigs);
// Use the data to spawn objects
level001Data.pigs.forEach(pigData => {
this.spawnPig(pigData.x, pigData.y, pigData.type);
});
level001Data.blocks.forEach(blockData => {
this.spawnBlock(blockData.x, blockData.y, blockData.material);
});
}
For type-safe JSON level loading, use Ajv for runtime validation:
import Ajv, { JSONSchemaType } from 'ajv';
// Define your level schema
interface LevelData {
id: string;
name: string;
birds: string[];
pigs: Array<{ x: number; y: number; type: string }>;
blocks: Array<{ x: number; y: number; material: string; rotation: number }>;
starThresholds: { one: number; two: number; three: number };
}
const levelSchema: JSONSchemaType<LevelData> = {
type: 'object',
required: ['id', 'name', 'birds', 'pigs', 'blocks', 'starThresholds'],
properties: {
id: { type: 'string' },
name: { type: 'string' },
birds: { type: 'array', items: { type: 'string' } },
pigs: {
type: 'array',
items: {
type: 'object',
required: ['x', 'y', 'type'],
properties: {
x: { type: 'number' },
y: { type: 'number' },
type: { type: 'string' }
}
}
},
blocks: {
type: 'array',
items: {
type: 'object',
required: ['x', 'y', 'material', 'rotation'],
properties: {
x: { type: 'number' },
y: { type: 'number' },
material: { type: 'string' },
rotation: { type: 'number' }
}
}
},
starThresholds: {
type: 'object',
required: ['one', 'two', 'three'],
properties: {
one: { type: 'number' },
two: { type: 'number' },
three: { type: 'number' }
}
}
}
};
// Validate before using
const ajv = new Ajv();
const validate = ajv.compile(levelSchema);
const levelData = this.cache.json.get('level001');
if (!validate(levelData)) {
console.error('Invalid level data:', validate.errors);
throw new Error('Level validation failed');
}
For dynamic level loading at runtime, use Phaser's plugin system:
class LevelLoaderPlugin extends Phaser.Plugins.BasePlugin {
constructor(pluginManager: Phaser.Plugins.PluginManager) {
super(pluginManager);
}
async loadLevel(levelId: string): Promise<any> {
const scene = this.scene;
const response = await fetch(`data/levels/${levelId}.json`);
const levelData = await response.json();
// Validate schema
if (!this.validateLevel(levelData)) {
throw new Error(`Invalid level data for ${levelId}`);
}
return levelData;
}
private validateLevel(data: any): boolean {
// Schema validation logic
return true;
}
}
| Issue | Solution |
|---|---|
| Assets not loading | Check preload() runs before create() |
| Physics not working | Verify physics config and body type |
| Scene not updating | Check scene is active: true |
| Canvas size wrong | Configure scale manager |
| Memory leaks | Clean up in shutdown() |
| JSON not loading | Verify file path and file extension |
| Invalid level data | Add schema validation with Ajv |
Complete Developer workflow orchestration - task research sequence, implementation flow, validation gates, PRD synchronization, exit conditions.
Complete Game Designer workflow - skill invocation protocol, GDD creation, playtest flow with GDD review, design sessions. MUST load before starting assignments.
Complete PM Coordinator workflow - task assignment, project orchestration, PRD management, worker coordination. Use proactively when starting PM agent work.
Complete PM Coordinator workflow - task assignment, project orchestration, PRD management, worker coordination. Use proactively when starting PM agent work.
Complete QA Validator workflow orchestration. References specialized skills for each validation step. Load at session startup for full protocol.
Base instructions and guidelines for all agents in the system. This skill provides foundational behaviors and communication protocols that all agents should follow.