Skip to main content
dev-phaser-particles Particle emitters for visual effects like fire, smoke, explosions, and magic
Jump to install Skills Marketplace Discover and explore AI skills built by the community.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Copy promptShow prompt details A direct command skips the review prompt. Inspect the source before running it.
npx skills add https://github.com/feliperyba/ralph-orchestra --skill dev-phaser-particlesThe command stays on one line. Scroll horizontally to inspect it before copying.
Prefer a local copy? Download the files currently available to SkillsMP.
Download Zip Downloading... Related occupations SOC
Based on SOC occupation classification
name dev-phaser-particles description Particle emitters for visual effects like fire, smoke, explosions, and magic
Phaser Particles
"Create stunning visual effects with particle systems."
Before/After: Manual Particle System vs Phaser Particles
❌ Before: Manual Particle Management
class Particle {
x : number ;
y : number ;
vx : number ;
vy : number ;
life : number ;
maxLife : number ;
size : number ;
alpha : number ;
color : string ;
constructor (x : number , y : number ) {
this .x = x;
this .y = y;
const angle = Math . () * . * ;
speed = + . () * ;
. = . (angle) * speed;
. = . (angle) * speed;
. = ;
. = + . () * ;
. = + . () * ;
. = ;
. = ;
}
( : ): {
. += . * dt / ;
. += . * dt / ;
. += * dt / ;
. += dt;
. = - ( . / . );
. < . ;
}
( ) {
ctx. = . ;
ctx. = . ;
ctx. ();
ctx. ( . , . , . , , . * );
ctx. ();
ctx. = ;
}
}
{
: [] = [];
( ) {
( i = ; i < count; i++) {
. . ( (x, y));
}
}
( ) {
. = . . ( p. (dt));
}
( ) {
( p . ) {
p. (ctx);
}
}
}
random
Math
PI
2
const
50
Math
random
200
this
vx
Math
cos
this
vy
Math
sin
this
life
0
this
maxLife
500
Math
random
500
this
size
2
Math
random
4
this
alpha
1
this
color
`hsl(${Math .random() * 60 + 10 } , 100%, 50%)`
update
dt
number
boolean
this
x
this
vx
1000
this
y
this
vy
1000
this
vy
200
1000
this
life
this
alpha
1
this
life
this
maxLife
return
this
life
this
maxLife
render
ctx : CanvasRenderingContext2D
globalAlpha
this
alpha
fillStyle
this
color
beginPath
arc
this
x
this
y
this
size
0
Math
PI
2
fill
globalAlpha
1
class
ParticleSystem
private
particles
Particle
explode
x : number , y : number , count : number
for
let
0
this
particles
push
new
Particle
update
dt : number
this
particles
this
particles
filter
p =>
update
render
ctx : CanvasRenderingContext2D
for
const
of
this
particles
render
✅ After: Phaser Particle System
export class GameScene extends Phaser.Scene {
create ( ) {
const explosion = this .add .particles (0 , 0 , 'explosion' , {
speed : { min : 100 , max : 400 },
angle : { min : 0 , max : 360 },
scale : { start : 0.5 , end : 2 },
alpha : { start : 1 , end : 0 },
lifespan : 600 ,
quantity : 30 ,
emitting : false ,
blendMode : 'ADD'
});
explosion.explode (30 , 400 , 300 );
const fire = this .add .particles (400 , 500 , 'fire' , {
speed : { min : 50 , max : 100 },
angle : { min : 240 , max : 300 },
scale : { start : 0.5 , end : 0 },
alpha : { start : 0.8 , end : 0 },
blendMode : 'ADD' ,
lifespan : 800 ,
frequency : 50 ,
quantity : 3
});
const trail = this .add .particles (0 , 0 , 'trail' , {
speed : 0 ,
scale : { start : 0.8 , end : 0 },
alpha : { start : 0.5 , end : 0 },
lifespan : 300 ,
quantity : 1 ,
frequency : 50 ,
emitZone : {
type : 'edge' ,
source : new Phaser .Geom .Circle (0 , 0 , 20 ),
quantity : 3
}
});
trail.startFollow (this .player );
const sparkles = this .add .particles (400 , 300 , 'sparkle' , {
speed : { min : 50 , max : 150 },
scale : { start : 0 , end : 0.5 , ease : 'Back.easeOut' },
alpha : { start : 1 , end : 0 },
lifespan : { min : 500 , max : 1000 },
onEmit : (particle : any ) => {
particle.tint = Phaser .Utils .Array .GetRandom ([
0xff0000 , 0x00ff00 , 0x0000ff
]);
}
});
}
}
When to Use This Skill
Creating explosion effects
Adding fire/smoke effects
Building magic spells
Implementing weather effects
Adding visual polish to actions
Quick Start create ( ) {
const particles = this .add .particles (0 , 0 , 'flare' , {
speed : 100 ,
scale : { start : 1 , end : 0 },
blendMode : 'ADD'
});
particles.startFollow (this .player );
}
Decision Framework Need Use Trail effect startFollow() + emittingExplosion One-time burst emitter Continuous effect Always-on emitter Zone-based emission Emitter zone Texture animation Animated particle frames
Progressive Guide
Level 1: Basic Particle Emitter export class GameScene extends Phaser.Scene {
create ( ) {
const particles = this .add .particles (400 , 300 , "flare" , {
speed : 100 ,
scale : { start : 1 , end : 0 },
blendMode : "ADD" ,
lifespan : 1000 ,
quantity : 1 ,
});
this .input .on ("pointermove" , (pointer : Phaser .Input .Pointer ) => {
particles.emitParticleAt (pointer.x , pointer.y );
});
}
}
Level 2: Common Effects create ( ) {
const fire = this .add .particles (400 , 500 , 'fire' , {
speed : { min : 50 , max : 100 },
angle : { min : 240 , max : 300 },
scale : { start : 0.5 , end : 0 },
blendMode : 'ADD' ,
lifespan : 800 ,
frequency : 50 ,
quantity : 3
});
const smoke = this .add .particles (400 , 480 , 'smoke' , {
speed : 30 ,
angle : { min : 250 , max : 290 },
scale : { start : 0.3 , end : 1 },
alpha : { start : 0.5 , end : 0 },
lifespan : 2000 ,
frequency : 100
});
const createExplosion = (x : number , y : number ) => {
const explosion = this .add .particles (x, y, 'explosion' , {
speed : { min : 100 , max : 300 },
angle : { min : 0 , max : 360 },
scale : { start : 0.5 , end : 2 },
alpha : { start : 1 , end : 0 },
lifespan : 500 ,
quantity : 30 ,
emitting : false
});
explosion.explode (30 , x, y);
};
this .input .on ('pointerdown' , (pointer : Phaser .Input .Pointer ) => {
createExplosion (pointer.x , pointer.y );
});
}
Level 3: Following Emitters export class GameScene extends Phaser.Scene {
private trailEmitter!: Phaser .GameObjects .Particles .ParticleEmitter ;
create ( ) {
this .player = this .add .image (400 , 300 , "player" );
this .trailEmitter = this .add .particles (0 , 0 , "trail" , {
speed : 0 ,
scale : { start : 0.8 , end : 0 },
alpha : { start : 0.5 , end : 0 },
lifespan : 300 ,
quantity : 1 ,
frequency : 50 ,
emitZone : {
type : "edge" ,
source : new Phaser .Geom .Circle (0 , 0 , 20 ),
quantity : 3 ,
},
});
this .trailEmitter .startFollow (this .player );
const exhaust = this .add .particles (0 , 20 , "exhaust" , {
speedX : { min : -20 , max : 20 },
speedY : { min : 50 , max : 100 },
scale : { start : 0.3 , end : 0 },
alpha : { start : 0.8 , end : 0 },
lifespan : 400 ,
frequency : 30 ,
});
exhaust.startFollow (this .player );
}
}
Level 4: Advanced Particle Configurations create ( ) {
const sparkles = this .add .particles (400 , 300 , 'sparkle' , {
speed : { min : 50 , max : 150 },
angle : { min : 0 , max : 360 },
scale : { start : 0 , end : 0.5 , ease : 'Back.easeOut' },
alpha : { start : 1 , end : 0 , ease : 'Linear' },
lifespan : { min : 500 , max : 1000 },
quantity : 2 ,
frequency : 100 ,
blendMode : 'ADD' ,
rotate : { start : 0 , end : 180 },
emitting : true
});
const rainZone = new Phaser .Geom .Rectangle (0 , 0 , this .scale .width , 20 );
const rain = this .add .particles (0 , 0 , 'rain' , {
x : { min : 0 , max : this .scale .width },
y : -20 ,
speedY : 400 ,
speedX : 0 ,
scale : { start : 0.3 , end : 0.3 },
alpha : { start : 0.5 , end : 0.8 },
lifespan : 2000 ,
quantity : 5 ,
frequency : 20 ,
emitZone : { source : rainZone }
});
const burstEmitter = this .add .particles (400 , 300 , 'particle' , {
speed : 200 ,
scale : { start : 1 , end : 0 },
alpha : { start : 1 , end : 0 },
lifespan : 1000 ,
quantity : 50 ,
emitting : false ,
onEmit : (particle : any ) => {
particle.tint = Phaser .Utils .Array .GetRandom ([0xff0000 , 0x00ff00 , 0x0000ff ]);
}
});
this .input .on ('pointerdown' , (pointer : Phaser .Input .Pointer ) => {
burstEmitter.explode (50 , pointer.x , pointer.y );
});
}
Level 5: Particle System Manager class ParticleManager {
private emitters = new Map <
string ,
Phaser .GameObjects .Particles .ParticleEmitter
>();
constructor (private scene : Phaser .Scene ) {
this .createPresets ();
}
private createPresets ( ) {
this .createEmitter ("fire" , {
key : "fire" ,
config : {
speed : { min : 50 , max : 100 },
angle : { min : 240 , max : 300 },
scale : { start : 0.5 , end : 0 },
alpha : { start : 0.8 , end : 0 },
blendMode : "ADD" ,
lifespan : 800 ,
frequency : 50 ,
},
});
this .createEmitter ("explosion" , {
key : "explosion" ,
config : {
speed : { min : 100 , max : 400 },
angle : { min : 0 , max : 360 },
scale : { start : 0.3 , end : 1 },
alpha : { start : 1 , end : 0 },
lifespan : 600 ,
quantity : 30 ,
emitting : false ,
},
});
this .createEmitter ("trail" , {
key : "trail" ,
config : {
speed : 50 ,
scale : { start : 0.5 , end : 0 },
alpha : { start : 0.6 , end : 0 },
lifespan : 400 ,
frequency : 50 ,
},
});
}
createEmitter (name : string , { key, config }: any ) {
const emitter = this .scene .add .particles (0 , 0 , key, config);
this .emitters .set (name, emitter);
return emitter;
}
emit (name : string , x : number , y : number ) {
const emitter = this .emitters .get (name);
if (emitter) {
emitter.explode (emitter.config .quantity || 10 , x, y);
}
}
follow (name : string , target : Phaser .GameObjects .GameObject ) {
const emitter = this .emitters .get (name);
if (emitter) {
emitter.startFollow (target);
}
}
stop (name : string ) {
const emitter = this .emitters .get (name);
if (emitter) {
emitter.stop ();
}
}
start (name : string ) {
const emitter = this .emitters .get (name);
if (emitter) {
emitter.start ();
}
}
destroy (name : string ) {
const emitter = this .emitters .get (name);
if (emitter) {
emitter.destroy ();
this .emitters .delete (name);
}
}
}
export class GameScene extends Phaser.Scene {
private particles!: ParticleManager ;
create ( ) {
this .particles = new ParticleManager (this );
this .particles .follow ("trail" , this .player );
this .input .on ("pointerdown" , (pointer : Phaser .Input .Pointer ) => {
this .particles .emit ("explosion" , pointer.x , pointer.y );
});
}
}
Anti-Patterns
Create too many particles per frame
Use large particle textures for small effects
Forget to stop emitters when done
Overuse blend modes (can kill performance)
Create particles in update() loop
Ignore particle lifespan
Limit particle count for mobile
Use appropriate particle sizes
Stop/remove unused emitters
Use blend modes sparingly
Create emitters once in create()
Tune lifespan for desired effect
Code Patterns
Emit Zones
const rectZone = new Phaser .Geom .Rectangle (x, y, width, height);
particles.setEmitZone ({
type : "random" ,
source : rectZone,
});
const edgeZone = new Phaser .Geom .Circle (x, y, radius);
particles.setEmitZone ({
type : "edge" ,
source : edgeZone,
quantity : 20 ,
});
const pointZone = new Phaser .Geom .Circle (x, y, radius);
particles.setEmitZone ({
type : "random" ,
source : pointZone,
});
Death Zones
const deathZone = new Phaser .Geom .Rectangle (300 , 200 , 200 , 200 );
particles.setDeathZone ({
type : "onEnter" ,
source : deathZone,
});
Particle Callbacks const particles = this .add .particles (400 , 300 , "spark" , {
speed : 100 ,
lifespan : 1000 ,
onEmit : (particle : any ) => {
particle.tint = 0xff0000 ;
particle.velocity .x *= Math .random ();
},
onParticleEmit : (emitter, particle ) => {
},
onParticleDeath : (emitter, particle ) => {
},
});
Emitter Configuration Reference Property Type Description speednumber/min/max Particle velocity anglenumber/min/max Emission angle scalestart/end Size over life alphastart/end Opacity over life lifespannumber/min/max Particle duration (ms) quantitynumber Particles per emission frequencynumber Time between emissions (ms) blendModestring Rendering blend mode rotatestart/end Rotation over life emitZoneobject Zone for emission deathZoneobject Zone for death
Common Blend Modes Mode Description Use For NORMALDefault Most effects ADDAdditive Fire, sparks, magic MULTIPLYMultiply Shadows, smoke SCREENScreen Glowing effects
Checklist
Reference More from this repository 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.