Skip to main content
writing-phaser-3-games Provides battle-tested patterns, best practices, and code examples for building Phaser 3 games. Use when writing game code, implementing game mechanics, setting up scenes, handling physics, animations, input, or any Phaser-related development. Covers architecture, performance, algorithms, and common pitfalls.
Aller à l'installation Skills Marketplace Découvrez et explorez les compétences IA créées par la communauté.
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Copier le promptAfficher les détails du prompt Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
npx skills add https://github.com/pmarashian/cursor-agent-skills --skill writing-phaser-3-gamesLa commande reste sur une seule ligne. Faites défiler horizontalement pour la vérifier avant de la copier.
Vous préférez une copie locale ? Téléchargez les fichiers actuellement disponibles dans SkillsMP.
Télécharger Zip Téléchargement... Plus depuis ce dépôt capacitor-vite-nextjs-backend Setup and patterns for a Vite + React frontend with Capacitor and Ionic React, plus a separate Next.js backend in a monorepo. Use when creating or modifying a Capacitor mobile app with a Vite frontend and Next.js API, or when adding Capacitor to an existing Vite app with a Next.js backend.
Modify Cursor/VSCode user settings in settings.json. Use when the user wants to change editor settings, preferences, configuration, themes, font size, tab size, format on save, auto save, keybindings, or any settings.json values.
Automates browser interactions for web testing, form filling, screenshots, and data extraction. Use when the user needs to navigate websites, interact with web pages, fill forms, take screenshots, test web applications, or extract information from web pages.
Explorateur de fichiers
21 fichiers Métiers associés SOC
Basé sur la classification professionnelle SOC
name Writing Phaser 3 Games description Provides battle-tested patterns, best practices, and code examples for building Phaser 3 games. Use when writing game code, implementing game mechanics, setting up scenes, handling physics, animations, input, or any Phaser-related development. Covers architecture, performance, algorithms, and common pitfalls.
Phaser 3 Game Development Skill
Quick Start
Most Common Patterns
Multi-Scene Flow
const config = {
scene : [ Boot , Preloader , MainMenu , Game , GameOver ]
};
Object Pooling
create ( ) {
this .projectiles = this .physics .add .group ({
classType : Projectile ,
frameQuantity : 20 ,
active : false ,
visible : false
});
}
fire ( ) {
const projectile = . . ( );
(projectile) projectile. (x, y);
}
this
projectiles
getFirstDead
false
if
fire
this .anims .create ({
key : 'walk' ,
frames : this .anims .generateFrameNumbers ('player' , { start : 0 , end : 3 }),
frameRate : 10 ,
repeat : -1
});
if (Phaser .Input .Keyboard .JustDown (this .spacebar )) {
this .jump ();
}
Navigation Guide
How to Use This Skill This skill provides access to 18 comprehensive pattern files covering all aspects of Phaser 3 development. Each file contains detailed patterns, code examples, and best practices.
To find specific patterns:
Read knowledgebase/06-input-handling.md
grep -r "object pooling" knowledgebase/
grep -i "animation" knowledgebase/*.md
grep -i "collision" knowledgebase/*.md
01 = Scene Architecture
02 = Asset Management
03 = Physics & Collision
04 = Movement Patterns
05 = Animation System
06 = Input Handling
07 = State Management
08 = Object Pooling & Memory
09 = Grid Systems
10 = Custom Game Objects
11 = UI/HUD Patterns
12 = Tween & Visual Effects
13 = Audio Integration
14 = Game Loop Patterns
15 = Algorithm Implementations
16 = Performance Optimization
17 = Code Organization
18 = Development Philosophy
Table of Contents
1. Scene Architecture Multi-scene flow, parallel scenes for UI overlays, scene transitions with effects, data passing between scenes.
Boot → Preloader → MainMenu → Game → GameOver flow
Parallel UI scene with scene.launch()
Camera fade transitions
Scene data passing via init(data)
2. Asset Management Two-stage loading, texture atlases, multi-format audio, font synchronization.
Bootstrap assets in Boot, full assets in Preloader
Texture atlas for multiple sprites
Multi-format audio for browser compatibility
WebFont loading synchronization
3. Physics & Collision Physics configuration, collision vs overlap, dynamic responses, state-gated collision.
Collider for physical blocking, overlap for triggers
Position-based dynamic response (paddle hits)
State-gated collision checks
Per-track/layer collision isolation
4. Movement Patterns Velocity-based, time-based discrete, timer-based, pursuit, direction validation, screen wrapping.
Velocity-based for continuous action games
Time-based discrete for grid games
Timer-based for turn-based games
Direction validation (prevent 180° turns)
5. Animation System Global animation creation, reverse animations, animation-driven logic, state-based control.
Create animations once in Preloader, use everywhere
Animation events for gameplay synchronization
State-based animation control with caching
External animation JSON data
6. Input Handling Keyboard, pointer, touch, JustDown pattern, dual input support, input gating, cleanup.
JustDown for single-press detection
Dual keyboard + pointer support
Input gating during animations
Event-driven pointer movement
One-time input with once()
7. State Management Scene-level state, registry for persistence, localStorage, GameObject data component, state machines.
Constructor for config, init() for resettable state
Registry for cross-scene data
GameObject data component for custom properties
Boolean flags vs state machines
8. Object Pooling & Memory Group-based pooling, enable/disable pattern, object reuse, dynamic texture cleanup.
Pre-create with frameQuantity, recycle with getFirstDead()
Enable/disable instead of create/destroy
Reset pattern for reusable objects
Dynamic texture cleanup prevention
9. Grid Systems Dual coordinates, 2D arrays, adjacency helpers, grid alignment, visualization.
Separate grid coordinates from pixel coordinates
2D array with bounds checking
Adjacency helpers (8-direction, 4-direction)
Grid-aligned group creation
10. Custom Game Objects Extending Sprite/Image, composition pattern, extending groups, self-registration.
Extend Sprite when physics + animations needed
Extend Image for static sprites with physics
Composition for non-visual managers
Must call super.preUpdate() for animations
11. UI/HUD Patterns Text styling, positioning, dynamic updates, bitmap fonts, icon counters, layering.
Text origin for positioning (top-left, center, etc.)
Animated counters with tweens
Icon-based counters (hearts, lives)
Depth/z-ordering for layered UI
12. Tween & Visual Effects Basic tweens, staggered animations, choreographed sequences, camera effects, particles.
Tween callbacks for sequencing
Staggered grid animations
Choreographed sequences with accumulating delays
Camera shake, flash, fade
Particle emitters
13. Audio Integration Sound management, audio lock handling, centralized audio, delayed/sequenced audio.
Multi-format audio loading
Audio lock detection and handling
Centralized audio management in UI scene
Persistent music across scenes
14. Game Loop Patterns Standard update, minimal event-driven, preUpdate for custom objects, delegation, timers.
Early exit guards in update()
Event-driven for turn-based games
Timer-based recurring/one-shot events
Update delegation to managers
15. Algorithm Implementations Flood fill, smart random placement, solvable puzzle generation, proximity calculation, following chains, AI.
Recursive flood fill with 4-direction spread
Valid position collection for guaranteed placement
Walker algorithm for solvable puzzles
Following chain with ShiftPosition
16. Performance Optimization Object pooling, texture caching, minimize update logic, event-driven, static groups.
Object pooling eliminates GC pauses
Static groups for immovable objects
Event-driven over polling in update()
Texture atlas for rendering performance
17. Code Organization File structure, ES6 modules, constants management, separation of concerns.
Scenes, gameobjects, managers, utils, constants folders
ES6 module imports
Constant files for sprite/animation/audio keys
Clear initialization order in create()
18. Development Philosophy Architecture principles, when to use physics, scene decisions, update vs events, progressive difficulty.
When to use physics vs manual logic
Single vs multi vs parallel scenes
Update() vs event-driven approaches
Progressive difficulty patterns
Core Patterns Reference
Scene Setup export default class Game extends Phaser.Scene {
constructor ( ) {
super ('Game' );
this .GRID_SIZE = 32 ;
}
init ( ) {
this .score = 0 ;
this .gameOver = false ;
}
create ( ) {
this .player = new Player (this );
this .enemies = this .physics .add .group ();
this .physics .add .collider (this .player , this .enemies , this .onHit , null , this );
}
update (time, delta ) {
if (this .gameOver ) return ;
}
}
Custom Game Object export default class Player extends Phaser.Physics.Arcade.Sprite {
constructor (scene, x, y ) {
super (scene, x, y, 'player' );
scene.add .existing (this );
scene.physics .add .existing (this );
this .setCollideWorldBounds (true );
this .isAlive = true ;
}
preUpdate (time, delta ) {
super .preUpdate (time, delta);
if (!this .isAlive ) return ;
this .handleMovement ();
}
}
Grid System
this .gridX = 5 ;
this .gridY = 3 ;
this .sprite .x = this .gridX * TILE_SIZE ;
this .sprite .y = this .gridY * TILE_SIZE ;
getCellXY (x, y ) {
if (x < 0 || x >= this .width || y < 0 || y >= this .height ) {
return null ;
}
return this .grid [y][x];
}
Collision Handling
this .physics .add .collider (player, platforms);
this .physics .add .overlap (player, coins, this .collectCoin , null , this );
onHit (player, enemy ) {
if (!player.isAlive ) return ;
if (player.invincible ) return ;
if (enemy.alpha < 1 ) return ;
this .handleDamage (player, enemy);
}
Input Patterns create ( ) {
this .cursors = this .input .keyboard .createCursorKeys ();
this .spacebar = this .input .keyboard .addKey (Phaser .Input .Keyboard .KeyCodes .SPACE );
this .input .on ('pointerdown' , this .handleClick , this );
}
update ( ) {
if (this .cursors .left .isDown ) {
this .player .setVelocityX (-160 );
}
if (Phaser .Input .Keyboard .JustDown (this .spacebar )) {
this .jump ();
}
}
Animation Setup
this .anims .create ({
key : 'player-walk' ,
frames : this .anims .generateFrameNumbers ('player' , { start : 0 , end : 3 }),
frameRate : 10 ,
repeat : -1
});
this .player .play ('player-walk' );
this .player .on ('animationcomplete-attack' , this .spawnProjectile , this );
State Management
init ( ) {
this .score = 0 ;
this .lives = 3 ;
this .gameOver = false ;
}
this .registry .set ('highscore' , this .score );
const highscore = this .registry .get ('highscore' );
sprite.setData ({ gridX : 5 , gridY : 3 , type : 'enemy' });
const gridX = sprite.data .values .gridX ;
Common Pitfalls Critical mistakes to avoid:
Forgetting super.preUpdate(time, delta) in custom sprites
Animations won't work without this
Always call first thing in preUpdate()
Not calling refreshBody() after scaling static groups
this .platforms .create (x, y, 'platform' )
.setScale (2 )
.refreshBody ();
Creating objects in update() instead of pooling
Causes GC pauses and poor performance
Pre-create pools, recycle with enable/disable
Missing bounds checks on grid access
if (x < 0 || x >= width || y < 0 || y >= height) return null ;
Not cleaning up listeners/timers
shutdown ( ) {
this .input .off ('pointerdown' , this .handleClick );
if (this .timer ) this .timer .remove ();
}
Using wrong collision method
Use collider for physical blocking
Use overlap for triggers/pickups
Polling in update() when events would work
Use physics overlap instead of distance checks
Use pointer events instead of checking every frame
Hard-coding values instead of constants
sprite.x = 400 ;
const GRID_SIZE = 32 ;
sprite.x = gridX * GRID_SIZE ;
Not resetting state in init()
Scene restart won't work properly
Put all resettable state in init(), not constructor
Ignoring context binding in callbacks
this .time .delayedCall (1000 , () => this .start (), [], this );
Performance Tips
Object pools for frequently created/destroyed objects
Texture atlases combine sprites into single image
Static groups for immovable platforms/walls
Event-driven over polling in update()
Minimal update logic - only what's necessary each frame
Cache lookups - don't search arrays every frame
Set depth once - don't sort every frame
When to Read Detailed Files
Quick Reference Cheat Sheet
Scene Flow Boot → Preloader → MainMenu → Game → GameOver
this .scene .start ('NextScene' , { score : this .score });
this .scene .launch ('GameUI' );
Physics this .physics .add .collider (a, b);
this .physics .add .overlap (a, b, callback);
sprite.setCollideWorldBounds (true );
sprite.setImmovable (true );
Groups & Pooling this .items = this .physics .add .group ({ frameQuantity : 20 });
const item = this .items .getFirstDead (false );
item.enableBody (true , x, y, true , true );
item.disableBody (true , true );
Input this .cursors = this .input .keyboard .createCursorKeys ();
Phaser .Input .Keyboard .JustDown (key)
this .input .on ('pointerdown' , callback, this );
Tweens this .tweens .add ({
targets : sprite,
x : 400 ,
duration : 1000 ,
ease : 'Power2' ,
onComplete : () => {}
});
Camera this .cameras .main .shake (duration, intensity);
this .cameras .main .fadeOut (duration);
this .cameras .main .flash (duration, r, g, b);
Test Seam Setup Always include test seam in scene create() method
Expose game state, scene key, and common commands:
create ( ) {
window .__TEST__ = {
sceneKey : this .scene .key ,
gameState : () => this .gameState ,
commands : {
clickStartGame : () => {
this .scene .start ('GameScene' );
}
}
};
}
Document test seam in code comments for future reference.
Scene Navigation Use this.scene.start('SceneName', data) for transitions
Pass game state via data parameter:
this .scene .start ('GameOverScene' , {
score : this .gameState .score ,
level : this .gameState .level
});
create (data ?: any ) {
const score = data?.score || 0 ;
const level = data?.level || 1 ;
}
Clean up resources in scene shutdown() method. Document navigation flow in progress.txt.
HUD Implementation (Enhanced) Use Graphics objects for backgrounds (rounded rectangles):
const bg = this .add .graphics ();
bg.fillStyle (0x000000 , 0.7 );
bg.fillRoundedRect (10 , 10 , 200 , 50 , 5 );
bg.setDepth (100 );
Set depth to 100+ for HUD elements :
Background: depth 100
Text: depth 101+
Position relative to camera dimensions :
const x = this .cameras .main .width - 220 ;
const y = 10 ;
Update text in real-time via setText() :
this .timerText .setText ('01:00' );
Audio Integration (Enhanced) Load audio in scene preload() method :
preload ( ) {
this .load .audio ('bgMusic' , 'assets/music.mp3' );
}
Initialize AudioManager in create() method :
create ( ) {
this .bgMusic = this .sound .add ('bgMusic' , { loop : true });
}
Respect volume settings from localStorage :
const settings = loadSettings ();
this .bgMusic .setVolume (settings.musicVolume );
Use test seam to verify audio state :
window .__TEST__ = {
commands : {
getAudioState : () => ({
musicPlaying : this .bgMusic .isPlaying ,
volume : this .bgMusic .volume
})
}
};
This skill provides comprehensive Phaser 3 patterns. Read the detailed knowledgebase files for in-depth examples and advanced techniques.
Camera Management Patterns Camera zoom and centerOn() for full visibility:
this .cameras .main .setZoom (1.0 );
this .cameras .main .centerOn (canvasWidth / 2 , canvasHeight / 2 );
Viewport scaling with aspect ratio maintenance:
const viewportWidth = window .innerWidth ;
const viewportHeight = window .innerHeight ;
const gameWidth = 800 ;
const gameHeight = 600 ;
const scaleX = viewportWidth / gameWidth;
const scaleY = viewportHeight / gameHeight;
const scale = Math .min (scaleX, scaleY);
this .cameras .main .setZoom (scale);
window.innerWidth/innerHeight for viewport calculations:
const viewportWidth = window .innerWidth ;
const viewportHeight = window .innerHeight ;
this .cameras .main .setBounds (0 , 0 , gameWidth, gameHeight);
this .cameras .main .setScroll (0 , 0 );
Canvas centering with flexbox:
canvas {
display : block;
margin : 0 auto;
}
Audio Integration Patterns Loading audio in preload() method:
preload ( ) {
this .load .audio ('bgMusic' , 'assets/audio/music/bg-music.mp3' );
this .load .audio ('coinCollect' , 'assets/audio/sfx/coin-collect.mp3' );
}
Volume control integration with Settings:
create ( ) {
const settings = loadSettings ();
this .bgMusic = this .sound .add ('bgMusic' , { loop : true });
this .bgMusic .setVolume (settings.musicVolume );
this .coinSound = this .sound .add ('coinCollect' );
this .coinSound .setVolume (settings.sfxVolume );
}
Background music with looping:
create ( ) {
this .bgMusic = this .sound .add ('bgMusic' , { loop : true });
this .bgMusic .play ();
}
Sound effect triggering patterns:
collectCoin ( ) {
this .coinSound .play ();
this .gameState .score += 10 ;
}
Test seam commands for audio testing:
window .__TEST__ .commands = {
getAudioState : () => ({
musicPlaying : this .bgMusic ?.isPlaying || false ,
musicVolume : this .bgMusic ?.volume || 0 ,
sfxVolume : this .coinSound ?.volume || 0
}),
setMusicVolume : (volume : number ) => {
this .bgMusic ?.setVolume (volume);
}
};
Sprite Management Patterns Individual sprite images vs spritesheets:
this .load .image ('wizard-south' , 'assets/wizard-south.png' );
this .load .image ('wizard-north' , 'assets/wizard-north.png' );
this .load .spritesheet ('wizard' , 'assets/wizard-sheet.png' , {
frameWidth : 48 ,
frameHeight : 48
});
Proper scaling (setScale) and origin (setOrigin):
sprite.setScale (2.0 );
sprite.setOrigin (0.5 , 0.5 );
Texture existence checks (this.textures.exists()):
if (this .textures .exists ('wizard-south' )) {
this .wizard = this .add .sprite (100 , 100 , 'wizard-south' );
} else {
this .wizard = this .add .rectangle (100 , 100 , 48 , 48 , 0x0000ff );
console .warn ('Wizard texture not found, using placeholder' );
}
Fallback to placeholder graphics:
create ( ) {
if (this .textures .exists ('wizard-south' )) {
this .wizard = this .add .sprite (100 , 100 , 'wizard-south' );
} else {
this .wizard = this .add .rectangle (100 , 100 , 48 , 48 , 0x0000ff );
this .wizard .setStrokeStyle (2 , 0x000000 );
console .warn ('Using placeholder for wizard sprite' );
}
}
Union types for Sprite | Rectangle:
type SpriteOrRectangle = Phaser .GameObjects .Sprite | Phaser .GameObjects .Rectangle ;
function handleObject (obj : SpriteOrRectangle ) {
if (obj instanceof Phaser .GameObjects .Sprite ) {
} else {
}
}
Error Handling Patterns Retry logic with new seeds:
generateMaze (maxRetries = 3 ) {
for (let i = 0 ; i < maxRetries; i++) {
try {
const maze = this .mazeGenerator .generate (this .seed + i);
return maze;
} catch (error) {
console .warn (`Maze generation attempt ${i + 1 } failed:` , error);
if (i === maxRetries - 1 ) {
return this .createFallbackMaze ();
}
}
}
}
Fallback mechanisms for critical operations:
create ( ) {
try {
this .load .image ('wizard' , generatedAssetUrl);
} catch (error) {
console .warn ('Failed to load generated asset, using placeholder' );
this .load .image ('wizard' , 'assets/fallback/wizard.png' );
}
}
Try-catch in scene create() methods:
create ( ) {
try {
this .initScene ();
} catch (error) {
console .error ('Scene initialization failed:' , error);
this .createFallbackScene ();
}
}
Console warnings for debugging:
if (!this .textures .exists ('asset-key' )) {
console .warn ('Asset not found:' , 'asset-key' );
console .warn ('Using fallback placeholder' );
}
Test seam commands for error scenarios:
window .__TEST__ .commands = {
forceMazeFailure : () => {
this .mazeGenerator .forceFailure = true ;
},
restoreMazeGeneration : () => {
this .mazeGenerator .forceFailure = false ;
}
};