~1 min read

Particles

The particle emitter — common effects, configuration anatomy, and the performance tradeoffs that actually matter.

A particle emitter spawns many short-lived sprites with randomized properties and (optionally) interpolated lifetimes. Phaser 4 ships a single emitter class that covers everything from a smoke trail to a screen-shaking explosion.

The shape of an emitter

const emitter = this.add.particles(0, 0, 'spark', {
	speed: { min: 80, max: 160 },
	angle: { min: 250, max: 290 },
	scale: { start: 1, end: 0 },
	alpha: { start: 1, end: 0 },
	lifespan: 600,
	frequency: 30,        // ms between emissions; -1 means "explode mode"
	quantity: 1,          // particles per emission
	blendMode: 'ADD',
});
emitter.startFollow(player);

Two big ideas:

  • Per-particle randomness via range objects. speed: { min, max } randomizes the initial value; scale: { start, end } interpolates from start to end over the particle’s lifetime.
  • Per-emitter rate via frequency + quantity. Together they set “particles per second.” frequency: -1 switches to explosion mode — emit quantity particles at once when emitter.explode() is called.

A live example

A continuous spark trail that follows an invisible target moving in a circle.

Spark trail Phaser 4 · sandboxed

Explosion mode

const burst = this.add.particles(0, 0, 'spark', {
	speed: { min: 120, max: 260 },
	lifespan: 500,
	scale: { start: 1, end: 0 },
	emitting: false,         // don't auto-emit
});

// Later, on an event:
burst.emitParticleAt(player.x, player.y, 30);

emitting: false is the key — it suppresses the continuous flow so you can fire bursts manually.

Emitter zones

Spawn or kill particles in arbitrary shapes:

const emitter = this.add.particles(0, 0, 'spark', {
	emitZone: { type: 'edge', source: new Phaser.Geom.Circle(0, 0, 50), quantity: 64 },
	// or 'random' for area-fill spawning
});

emitZone controls where particles are born; deathZone removes any that enter a given shape — useful for “particles get absorbed into a pickup.”

Common recipes

Smoke — slow, large, fading, no additive blending.

{ speed: 20, scale: { start: 0.4, end: 1.6 }, alpha: { start: 0.6, end: 0 },
  lifespan: 1500, frequency: 80, blendMode: 'NORMAL' }

Explosion — fast, additive, single burst.

{ speed: { min: 200, max: 400 }, scale: { start: 1, end: 0 },
  lifespan: 400, blendMode: 'ADD', emitting: false }
// ...then emitter.explode(50, x, y);

Trail — high frequency, short lifespan, follows a target.

{ speed: 10, scale: { start: 0.5, end: 0 }, lifespan: 200,
  frequency: 10, follow: target, blendMode: 'ADD' }

Performance

  • ADD blending is the biggest cost. Switch to NORMAL if you don’t need the glow look.
  • Particle texture size matters more than count. A 1000-particle emitter with 8×8 sparks is cheaper than 100 particles with 256×256 puffs.
  • Cap concurrent particles with maxParticles — prevents pathological bursts when frequency × lifespan goes high.
  • Game Objects — the particle manager is itself a game object and can be added to containers.
  • Shaders — for effects beyond what blend modes can express.