用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/feliperyba/ralph-orchestra --skill dev-phaser-fundamentals命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
基于 SOC 职业分类
正在显示 SKILL.md
| 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
}
}
config = {
: [],
: { : },
};
.(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.();
.();
}
}
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
dt = delta / ;
}
}
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.);
});
level001Data..( {
.(blockData., blockData., blockData.);
});
}
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' },
: { : },
: { : , : { : } },
: {
: ,
: {
: ,
: [, , ],
: {
: { : },
: { : },
: { : }
}
}
},
: {
: ,
: {
: ,
: [, , , ],
: {
: { : },
: { : },
: { : },
: { : }
}
}
},
: {
: ,
: [, , ],
: {
: { : },
: { : },
: { : }
}
}
}
};
ajv = ();
validate = ajv.(levelSchema);
levelData = ...();
(!(levelData)) {
.(, validate.);
();
}
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.