particles

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Particle System

粒子系统

Creating and controlling particle effects in Phaser 4 -- ParticleEmitter creation and configuration, emitter ops (value formats), gravity wells, emission and death zones, flow vs burst modes, following game objects, and particle callbacks.
Key source paths:
src/gameobjects/particles/
Related skills: ../sprites-and-images/SKILL.md, ../loading-assets/SKILL.md
在Phaser 4中创建和控制粒子特效——包括ParticleEmitter的创建与配置、发射器操作(值格式)、引力井、发射与消亡区域、流动模式vs爆发模式、跟随游戏对象以及粒子回调。
核心源码路径:
src/gameobjects/particles/
相关技能: ../sprites-and-images/SKILL.md, ../loading-assets/SKILL.md

Quick Start

快速开始

js
// In a Scene's create() method:

// Basic continuous emitter (flow mode)
const emitter = this.add.particles(400, 300, 'flares', {
    frame: 'red',
    speed: 200,
    lifespan: 2000,
    scale: { start: 1, end: 0 },
    alpha: { start: 1, end: 0 },
    gravityY: 150
});

// One-shot burst (explode mode)
const burst = this.add.particles(400, 300, 'flares', {
    frame: 'blue',
    speed: { min: 100, max: 300 },
    lifespan: 1000,
    scale: { start: 0.5, end: 0 },
    emitting: false   // don't auto-start
});
burst.explode(20);    // emit 20 particles at once
js
// 在场景的create()方法中:

// 基础持续发射器(流动模式)
const emitter = this.add.particles(400, 300, 'flares', {
    frame: 'red',
    speed: 200,
    lifespan: 2000,
    scale: { start: 1, end: 0 },
    alpha: { start: 1, end: 0 },
    gravityY: 150
});

// 一次性爆发发射器(爆炸模式)
const burst = this.add.particles(400, 300, 'flares', {
    frame: 'blue',
    speed: { min: 100, max: 300 },
    lifespan: 1000,
    scale: { start: 0.5, end: 0 },
    emitting: false   // 不自动启动
});
burst.explode(20);    // 一次性发射20个粒子

Core Concepts

核心概念

ParticleEmitter

ParticleEmitter

ParticleEmitter
extends
GameObject
and is added directly to the display list. It is both a game object (positionable, scalable, maskable) and the emitter itself. There is no separate manager --
this.add.particles()
returns a
ParticleEmitter
instance.
Factory signature:
js
this.add.particles(x, y, texture, config);
// x, y: world position (both optional, default 0)
// texture: string key or Texture instance
// config: ParticleEmitterConfig object (optional, can call setConfig later)
Mixins: AlphaSingle, BlendMode, Depth, Lighting, Mask, RenderNodes, ScrollFactor, Texture, Transform, Visible. So you can call
setPosition()
,
setScale()
,
setDepth()
,
setBlendMode()
,
setMask()
,
setScrollFactor()
, etc.
ParticleEmitter
继承自
GameObject
,直接添加到显示列表中。它既是一个游戏对象(可定位、可缩放、可遮罩),同时也是发射器本身。没有单独的管理器——
this.add.particles()
会直接返回一个
ParticleEmitter
实例。
工厂方法签名:
js
this.add.particles(x, y, texture, config);
// x, y:世界坐标(均为可选参数,默认值0)
// texture:字符串键或Texture实例
// config:ParticleEmitterConfig对象(可选,可后续调用setConfig设置)
混入特性: AlphaSingle、BlendMode、Depth、Lighting、Mask、RenderNodes、ScrollFactor、Texture、Transform、Visible。因此你可以调用
setPosition()
setScale()
setDepth()
setBlendMode()
setMask()
setScrollFactor()
等方法。

Particle

Particle

A lightweight object owned by its emitter. Key properties:
x
,
y
,
velocityX/Y
,
accelerationX/Y
,
scaleX/Y
,
alpha
,
angle
,
rotation
,
tint
,
life
(total ms),
lifeCurrent
(remaining ms),
lifeT
(0-1 normalized),
bounce
,
delayCurrent
,
holdCurrent
. Particles are pooled internally -- you never create them manually.
由发射器拥有的轻量级对象。核心属性:
x
y
velocityX/Y
accelerationX/Y
scaleX/Y
alpha
angle
rotation
tint
life
(总时长,毫秒)、
lifeCurrent
(剩余时长,毫秒)、
lifeT
(0-1归一化值)、
bounce
delayCurrent
holdCurrent
。粒子在内部被池化——你永远不需要手动创建它们。

EmitterOp Value Formats

发射器操作值格式

Most config properties (speed, scale, alpha, angle, x, y, etc.) accept flexible value formats:
js
x: 400                                        // static value
x: [100, 200, 300, 400]                       // random pick from array
x: { min: 100, max: 700 }                     // random float in range
x: { min: 100, max: 700, int: true }          // random integer
x: { random: [100, 700] }                     // random integer shorthand
scale: { start: 0, end: 1 }                   // ease over lifetime (default linear)
scale: { start: 0, end: 1, ease: 'bounce.out' }  // custom ease
scale: { start: 4, end: 0.5, random: true }   // random start, ease to end
x: { values: [50, 500, 200, 800], interpolation: 'catmull' }  // interpolation
x: { steps: 32, start: 0, end: 576 }          // stepped sequential
x: { steps: 32, start: 0, end: 576, yoyo: true }  // stepped with yoyo
x: {                                           // custom callbacks
    onEmit: (particle, key, t, value) => value,
    onUpdate: (particle, key, t, value) => value
}
x: (particle, key, t, value) => value + 50    // emit-time callback shorthand
Emit-only (no onUpdate):
angle
,
delay
,
hold
,
lifespan
,
quantity
,
speedX
,
speedY
. Emit + Update (support start/end, onUpdate):
accelerationX/Y
,
alpha
,
bounce
,
maxVelocityX/Y
,
moveToX/Y
,
rotate
,
scaleX/Y
,
tint
,
x
,
y
.
大多数配置属性(speed、scale、alpha、angle、x、y等)支持灵活的取值格式:
js
x: 400                                        // 静态值
x: [100, 200, 300, 400]                       // 从数组中随机选取
x: { min: 100, max: 700 }                     // 范围内的随机浮点数
x: { min: 100, max: 700, int: true }          // 随机整数
x: { random: [100, 700] }                     // 随机整数简写
scale: { start: 0, end: 1 }                   // 生命周期内缓动(默认线性)
scale: { start: 0, end: 1, ease: 'bounce.out' }  // 自定义缓动
scale: { start: 4, end: 0.5, random: true }   // 随机起始值,缓动至结束值
x: { values: [50, 500, 200, 800], interpolation: 'catmull' }  // 插值
x: { steps: 32, start: 0, end: 576 }          // 分步序列
x: { steps: 32, start: 0, end: 576, yoyo: true }  // 带往返的分步序列
x: {                                           // 自定义回调
    onEmit: (particle, key, t, value) => value,
    onUpdate: (particle, key, t, value) => value
}
x: (particle, key, t, value) => value + 50    // 发射时回调简写
仅发射时生效(无onUpdate):
angle
delay
hold
lifespan
quantity
speedX
speedY
发射+更新时生效(支持start/end、onUpdate):
accelerationX/Y
alpha
bounce
maxVelocityX/Y
moveToX/Y
rotate
scaleX/Y
tint
x
y

Flow vs Explode (Burst)

流动模式 vs 爆发模式(Burst)

Flow mode (
frequency >= 0
): emits
quantity
particles every
frequency
ms. Default is
frequency: 0
(every frame) with
emitting: true
.
Explode mode (
frequency = -1
): emits a batch all at once, then stops.
js
emitter.flow(100, 5);           // 5 particles every 100ms
emitter.flow(100, 5, 50);       // auto-stop after 50 total
emitter.explode(30, 200, 400);  // burst 30 at position
emitter.explode(30);            // burst at emitter position
流动模式
frequency >= 0
):每隔
frequency
毫秒发射
quantity
个粒子。默认值为
frequency: 0
(每帧发射)且
emitting: true
爆发模式
frequency = -1
):一次性发射一批粒子,然后停止。
js
emitter.flow(100, 5);           // 每100毫秒发射5个粒子
emitter.flow(100, 5, 50);       // 发射满50个后自动停止
emitter.explode(30, 200, 400);  // 在指定位置爆发30个粒子
emitter.explode(30);            // 在发射器位置爆发粒子

Common Patterns

常见模式

Scale, Alpha, and Color Over Lifetime

生命周期内的缩放、透明度与颜色变化

js
// Scale and alpha with custom easing
this.add.particles(400, 300, 'spark', {
    lifespan: 2000,
    speed: 100,
    scale: { start: 1, end: 0, ease: 'power2' },
    alpha: { start: 1, end: 0, ease: 'cubic.in' }
});
js
// 带自定义缓动的缩放和透明度
this.add.particles(400, 300, 'spark', {
    lifespan: 2000,
    speed: 100,
    scale: { start: 1, end: 0, ease: 'power2' },
    alpha: { start: 1, end: 0, ease: 'cubic.in' }
});

Color Interpolation

颜色插值

The
color
property interpolates through an array of colors over particle lifetime (overrides
tint
):
js
this.add.particles(400, 300, 'spark', {
    lifespan: 2000, speed: 100, scale: { start: 0.5, end: 0 },
    color: [0xfacc22, 0xf89800, 0xf83600, 0x9f0404], colorEase: 'quad.out'
});
color
属性会在粒子生命周期内插值遍历颜色数组(会覆盖
tint
):
js
this.add.particles(400, 300, 'spark', {
    lifespan: 2000, speed: 100, scale: { start: 0.5, end: 0 },
    color: [0xfacc22, 0xf89800, 0xf83600, 0x9f0404], colorEase: 'quad.out'
});

Tinting Particles

粒子着色

js
this.add.particles(400, 300, 'spark', { tint: 0xff0000 });                           // static
this.add.particles(400, 300, 'spark', { tint: { start: 0xffffff, end: 0xff0000 } }); // over lifetime
js
this.add.particles(400, 300, 'spark', { tint: 0xff0000 });                           // 静态着色
this.add.particles(400, 300, 'spark', { tint: { start: 0xffffff, end: 0xff0000 } }); // 生命周期内渐变

Gravity Wells

引力井

A
GravityWell
applies inverse-square gravitational force, pulling (or repelling with negative
power
) particles toward a point.
js
const emitter = this.add.particles(400, 300, 'spark', {
    speed: 100, lifespan: 4000, scale: { start: 0.4, end: 0 }, quantity: 2
});

const well = emitter.createGravityWell({
    x: 400, y: 300, power: 2, epsilon: 100, gravity: 50
});

// Update at runtime
well.x = 300;
well.power = -1;  // negative = repel

// Or create manually and add
const well2 = new Phaser.GameObjects.Particles.GravityWell(500, 200, 3, 100, 50);
emitter.addParticleProcessor(well2);
emitter.removeParticleProcessor(well2);
GravityWell
应用平方反比引力,将粒子拉向(或使用负
power
推开)某个点。
js
const emitter = this.add.particles(400, 300, 'spark', {
    speed: 100, lifespan: 4000, scale: { start: 0.4, end: 0 }, quantity: 2
});

const well = emitter.createGravityWell({
    x: 400, y: 300, power: 2, epsilon: 100, gravity: 50
});

// 运行时更新
well.x = 300;
well.power = -1;  // 负值表示推开粒子

// 或者手动创建并添加
const well2 = new Phaser.GameObjects.Particles.GravityWell(500, 200, 3, 100, 50);
emitter.addParticleProcessor(well2);
emitter.removeParticleProcessor(well2);

Emission Zones (Random)

发射区域(随机)

A
RandomZone
spawns particles at random positions within a shape. The source must have a
getRandomPoint(point)
method -- all Phaser geometry classes (Circle, Ellipse, Rectangle, Triangle, Polygon, Line) support this, or provide a custom source:
js
// Using built-in geometry
this.add.particles(400, 300, 'spark', {
    speed: 50, lifespan: 2000,
    emitZone: { type: 'random', source: new Phaser.Geom.Circle(0, 0, 100) }
});

// Custom source object (any object with getRandomPoint)
emitter.addEmitZone({
    type: 'random',
    source: {
        getRandomPoint: (point) => {
            const a = Math.random() * Math.PI * 2;
            point.x = Math.cos(a) * 100;
            point.y = Math.sin(a) * 50;
            return point;
        }
    }
});
RandomZone
会在形状内的随机位置生成粒子。源对象必须拥有
getRandomPoint(point)
方法——所有Phaser几何类(Circle、Ellipse、Rectangle、Triangle、Polygon、Line)都支持此方法,也可以提供自定义源对象:
js
// 使用内置几何形状
this.add.particles(400, 300, 'spark', {
    speed: 50, lifespan: 2000,
    emitZone: { type: 'random', source: new Phaser.Geom.Circle(0, 0, 100) }
});

// 自定义源对象(任何拥有getRandomPoint方法的对象)
emitter.addEmitZone({
    type: 'random',
    source: {
        getRandomPoint: (point) => {
            const a = Math.random() * Math.PI * 2;
            point.x = Math.cos(a) * 100;
            point.y = Math.sin(a) * 50;
            return point;
        }
    }
});

Emission Zones (Edge)

发射区域(边缘)

An
EdgeZone
places particles sequentially along shape edges. The source must have a
getPoints(quantity, stepRate)
method. Curves, Paths, and all geometry shapes support this:
js
this.add.particles(400, 300, 'spark', {
    lifespan: 1500, speed: 20,
    emitZone: {
        type: 'edge',
        source: new Phaser.Geom.Circle(0, 0, 150),
        quantity: 48,     // number of points on edge (use 0 with stepRate instead)
        yoyo: false,      // reverse direction at ends
        seamless: true    // remove duplicate endpoint
    }
});

// Or add post-creation with any source that has getPoints
emitter.addEmitZone({ type: 'edge', source: geom, quantity: 50, yoyo: false, seamless: true });
Multiple emission zones: Pass an array to
emitZone
or call
addEmitZone()
multiple times. Zones iterate in sequence. The
total
property controls how many particles emit before rotating to the next zone (-1 = never rotate).
js
this.add.particles(400, 300, 'spark', {
    emitZone: [
        { type: 'random', source: new Phaser.Geom.Circle(0, 0, 50) },
        { type: 'random', source: new Phaser.Geom.Circle(200, 0, 50) }
    ]
});
EdgeZone
会沿形状边缘依次放置粒子。源对象必须拥有
getPoints(quantity, stepRate)
方法。曲线、路径以及所有几何形状都支持此方法:
js
this.add.particles(400, 300, 'spark', {
    lifespan: 1500, speed: 20,
    emitZone: {
        type: 'edge',
        source: new Phaser.Geom.Circle(0, 0, 150),
        quantity: 48,     // 边缘上的点数量(也可设为0并使用stepRate)
        yoyo: false,      // 是否在端点反向
        seamless: true    // 是否移除重复的端点
    }
});

// 或者创建后添加任何拥有getPoints方法的源对象
emitter.addEmitZone({ type: 'edge', source: geom, quantity: 50, yoyo: false, seamless: true });
多个发射区域:
emitZone
传入数组,或多次调用
addEmitZone()
。区域会按顺序循环使用。
total
属性控制发射多少个粒子后切换到下一个区域(-1表示永不切换)。
js
this.add.particles(400, 300, 'spark', {
    emitZone: [
        { type: 'random', source: new Phaser.Geom.Circle(0, 0, 50) },
        { type: 'random', source: new Phaser.Geom.Circle(200, 0, 50) }
    ]
});

Death Zones

消亡区域

A
DeathZone
kills particles when they enter (or leave) a region. The source must have a
contains(x, y)
method.
js
// Kill particles entering a rectangle
this.add.particles(400, 100, 'spark', {
    speed: 200, lifespan: 5000, gravityY: 100,
    deathZone: { type: 'onEnter', source: new Phaser.Geom.Rectangle(300, 400, 200, 50) }
});

// Kill particles leaving a circle (confine to area)
this.add.particles(400, 300, 'spark', {
    speed: 100, lifespan: 5000,
    deathZone: { type: 'onLeave', source: new Phaser.Geom.Circle(400, 300, 150) }
});

// Custom death zone source (any object with contains)
emitter.addDeathZone({
    type: 'onEnter',
    source: { contains: (x, y) => x > 600 && y > 400 }
});
DeathZone
会在粒子进入(或离开)某个区域时将其销毁。源对象必须拥有
contains(x, y)
方法。
js
// 销毁进入矩形区域的粒子
this.add.particles(400, 100, 'spark', {
    speed: 200, lifespan: 5000, gravityY: 100,
    deathZone: { type: 'onEnter', source: new Phaser.Geom.Rectangle(300, 400, 200, 50) }
});

// 销毁离开圆形区域的粒子(限制在区域内)
this.add.particles(400, 300, 'spark', {
    speed: 100, lifespan: 5000,
    deathZone: { type: 'onLeave', source: new Phaser.Geom.Circle(400, 300, 150) }
});

// 自定义消亡区域源对象(任何拥有contains方法的对象)
emitter.addDeathZone({
    type: 'onEnter',
    source: { contains: (x, y) => x > 600 && y > 400 }
});

Following a Game Object

跟随游戏对象

js
const player = this.add.sprite(100, 100, 'player');
const emitter = this.add.particles(0, 0, 'spark', {
    speed: 50, lifespan: 800, scale: { start: 0.5, end: 0 }
});

emitter.startFollow(player);                       // follow position
emitter.startFollow(player, 10, -20);              // with offset
emitter.startFollow(player, 0, 0, true);           // track visibility too
emitter.stopFollow();

// Or via config:
this.add.particles(0, 0, 'spark', { follow: player, followOffset: { x: 0, y: -20 } });
js
const player = this.add.sprite(100, 100, 'player');
const emitter = this.add.particles(0, 0, 'spark', {
    speed: 50, lifespan: 800, scale: { start: 0.5, end: 0 }
});

emitter.startFollow(player);                       // 跟随位置
emitter.startFollow(player, 10, -20);              // 带偏移量
emitter.startFollow(player, 0, 0, true);           // 同时跟踪可见性
emitter.stopFollow();

// 或者通过配置:
this.add.particles(0, 0, 'spark', { follow: player, followOffset: { x: 0, y: -20 } });

Particle Callbacks

粒子回调

js
// Via config
const emitter = this.add.particles(400, 300, 'spark', {
    speed: 100, lifespan: 2000,
    emitCallback: (particle, emitter) => { /* on emit */ },
    deathCallback: (particle) => { /* on death */ }
});

// Or set after creation
emitter.onParticleEmit((particle, emitter) => { /* ... */ });
emitter.onParticleDeath((particle) => { /* ... */ });

// Iterate alive/dead particles
emitter.forEachAlive((particle, emitter) => { /* particle.x, particle.lifeT */ });
js
// 通过配置
const emitter = this.add.particles(400, 300, 'spark', {
    speed: 100, lifespan: 2000,
    emitCallback: (particle, emitter) => { /* 发射时执行 */ },
    deathCallback: (particle) => { /* 消亡时执行 */ }
});

// 或者创建后设置
emitter.onParticleEmit((particle, emitter) => { /* ... */ });
emitter.onParticleDeath((particle) => { /* ... */ });

// 遍历存活/消亡的粒子
emitter.forEachAlive((particle, emitter) => { /* particle.x, particle.lifeT */ });

Duration, StopAfter, and Advance

持续时长、停止条件与预推进

js
// Auto-stop after 3 seconds (alive particles continue until they expire)
this.add.particles(400, 300, 'spark', { speed: 100, duration: 3000 });

// Emit exactly 50 particles then stop
this.add.particles(400, 300, 'spark', { speed: 100, stopAfter: 50 });

// Pre-warm: fast-forward 2 seconds so particles visible on first frame
this.add.particles(400, 300, 'spark', { speed: 100, lifespan: 2000, advance: 2000 });
// Or manually: emitter.fastForward(2000, 50);
js
// 3秒后自动停止(存活的粒子会继续直到生命周期结束)
this.add.particles(400, 300, 'spark', { speed: 100, duration: 3000 });

// 恰好发射50个粒子后停止
this.add.particles(400, 300, 'spark', { speed: 100, stopAfter: 50 });

// 预预热:快进2秒,使第一帧就可见粒子
this.add.particles(400, 300, 'spark', { speed: 100, lifespan: 2000, advance: 2000 });
// 或者手动操作:emitter.fastForward(2000, 50);

Particle Bounds (Bounce)

粒子边界(弹跳)

js
this.add.particles(400, 300, 'spark', {
    speed: 200, lifespan: 5000, bounce: 0.8,
    bounds: { x: 100, y: 100, width: 600, height: 400 },
    collideLeft: true, collideRight: true, collideTop: true, collideBottom: true
});
// Or: emitter.addParticleBounds(100, 100, 600, 400);
js
this.add.particles(400, 300, 'spark', {
    speed: 200, lifespan: 5000, bounce: 0.8,
    bounds: { x: 100, y: 100, width: 600, height: 400 },
    collideLeft: true, collideRight: true, collideTop: true, collideBottom: true
});
// 或者:emitter.addParticleBounds(100, 100, 600, 400);

Texture Frames and Animations

纹理帧与动画

js
// Random frame per particle
this.add.particles(400, 300, 'flares', { frame: ['red', 'green', 'blue'] });

// Sequential frames cycling through with quantity per frame
this.add.particles(400, 300, 'flares', {
    frame: { frames: ['red', 'green', 'blue'], cycle: true, quantity: 4 }
});

// Particle animation (plays anim over particle lifetime)
this.add.particles(400, 300, 'explosion', { anim: 'explode_anim', lifespan: 1000 });

// Multiple anims, randomly assigned
this.add.particles(400, 300, 'sheet', {
    anim: { anims: ['fire', 'smoke'], cycle: false, quantity: 1 }
});
js
// 每个粒子随机选取帧
this.add.particles(400, 300, 'flares', { frame: ['red', 'green', 'blue'] });

// 按顺序循环帧,每帧指定数量的粒子
this.add.particles(400, 300, 'flares', {
    frame: { frames: ['red', 'green', 'blue'], cycle: true, quantity: 4 }
});

// 粒子动画(在粒子生命周期内播放动画)
this.add.particles(400, 300, 'explosion', { anim: 'explode_anim', lifespan: 1000 });

// 多个动画,随机分配
this.add.particles(400, 300, 'sheet', {
    anim: { anims: ['fire', 'smoke'], cycle: false, quantity: 1 }
});

Sorting Particles

粒子排序

js
this.add.particles(400, 300, 'spark', { sortProperty: 'y', sortOrderAsc: true });
// Or: sortCallback: (a, b) => a.y - b.y
js
this.add.particles(400, 300, 'spark', { sortProperty: 'y', sortOrderAsc: true });
// 或者:sortCallback: (a, b) => a.y - b.y

Custom Particle Processor

自定义粒子处理器

Extend
ParticleProcessor
to apply custom per-particle logic each frame. Implement
update(particle, delta, step, t)
:
js
class WindProcessor extends Phaser.GameObjects.Particles.ParticleProcessor {
    constructor (windX, windY) {
        super(0, 0);
        this.windX = windX;
        this.windY = windY;
    }

    update (particle, delta, step, t) {
        particle.velocityX += this.windX * step;
        particle.velocityY += this.windY * step;
    }
}

emitter.addParticleProcessor(new WindProcessor(0.5, 0));
继承
ParticleProcessor
以实现每帧自定义粒子逻辑。实现
update(particle, delta, step, t)
方法:
js
class WindProcessor extends Phaser.GameObjects.Particles.ParticleProcessor {
    constructor (windX, windY) {
        super(0, 0);
        this.windX = windX;
        this.windY = windY;
    }

    update (particle, delta, step, t) {
        particle.velocityX += this.windX * step;
        particle.velocityY += this.windY * step;
    }
}

emitter.addParticleProcessor(new WindProcessor(0.5, 0));

Custom Particle Class

自定义粒子类

Extend
Particle
and override
update
for per-particle behavior. Set via
particleClass
in config:
js
class TrailParticle extends Phaser.GameObjects.Particles.Particle {
    update (delta, step, processors) {
        const result = super.update(delta, step, processors);
        this.alpha = this.lifeT;  // custom: alpha matches life progress
        return result;  // must return true if particle is still alive
    }
}

this.add.particles(400, 300, 'spark', {
    particleClass: TrailParticle,
    speed: 100, lifespan: 2000
});
继承
Particle
并覆盖
update
方法以实现粒子自定义行为。通过配置中的
particleClass
设置:
js
class TrailParticle extends Phaser.GameObjects.Particles.Particle {
    update (delta, step, processors) {
        const result = super.update(delta, step, processors);
        this.alpha = this.lifeT;  // 自定义:透明度与生命周期进度匹配
        return result;  // 必须返回true表示粒子仍存活
    }
}

this.add.particles(400, 300, 'spark', {
    particleClass: TrailParticle,
    speed: 100, lifespan: 2000
});

Configuration Reference

配置参考

ParticleEmitterConfig -- Simple Properties

ParticleEmitterConfig -- 简单属性

PropertyTypeDefaultDescription
active
boolean
true
False = emitter does not update at all
emitting
boolean
true
False = no new particles (alive ones still update)
blendMode
string/number
0
Blend mode for rendering
frequency
number
0
ms between flow cycles; 0 = every frame; -1 = explode
gravityX
,
gravityY
number
0
Gravity in px/s^2
maxParticles
number
0
Hard limit on total particle objects (0 = unlimited)
maxAliveParticles
number
0
Max alive particles at once (0 = unlimited)
duration
number
0
Auto-stop after ms (0 = forever)
stopAfter
number
0
Auto-stop after N particles emitted (0 = unlimited)
advance
number
0
Fast-forward on creation (ms)
radial
boolean
true
True = speed+angle; false = speedX/speedY
particleBringToTop
boolean
true
New particles render on top
timeScale
number
1
Time multiplier for updates
follow
Vector2Like
null
Object to follow
followOffset
Vector2LikeOffset from follow target
trackVisible
boolean
false
Match follow target's visibility
reserve
numberPre-allocate particle objects
particleClass
function
Particle
Custom particle class
sortProperty
stringParticle property to sort by
sortOrderAsc
booleanSort ascending if true
属性类型默认值描述
active
boolean
true
设为false时,发射器完全不更新
emitting
boolean
true
设为false时,不再发射新粒子(存活的粒子仍会更新)
blendMode
string/number
0
渲染混合模式
frequency
number
0
流动周期间隔(毫秒);0表示每帧发射;-1表示爆发模式
gravityX
,
gravityY
number
0
重力加速度(像素/秒²)
maxParticles
number
0
粒子对象总数上限(0表示无限制)
maxAliveParticles
number
0
同时存活的粒子数量上限(0表示无限制)
duration
number
0
自动停止前的持续时长(毫秒);0表示永久
stopAfter
number
0
自动停止前发射的粒子总数;0表示无限制
advance
number
0
创建时快进的时长(毫秒)
radial
boolean
true
设为true时使用speed+angle;设为false时使用speedX/speedY
particleBringToTop
boolean
true
新粒子渲染在最上层
timeScale
number
1
更新的时间乘数
follow
Vector2Like
null
要跟随的对象
followOffset
Vector2Like跟随目标的偏移量
trackVisible
boolean
false
是否匹配跟随目标的可见性
reserve
number预分配的粒子对象数量
particleClass
function
Particle
自定义粒子类
sortProperty
string用于排序的粒子属性
sortOrderAsc
boolean设为true时升序排序

ParticleEmitterConfig -- EmitterOp Properties

ParticleEmitterConfig -- 发射器操作属性

All accept the flexible value formats described above.
PropertyDefaultE/UDescription
x
,
y
0
E+UParticle offset from emitter
speed
0
ERadial speed (sets speedX, deactivates speedY)
speedX
,
speedY
0
EDirectional speed (sets radial=false)
angle
{min:0,max:360}
EEmission angle in degrees
scale
1
E+UUniform scale (sets scaleX, deactivates scaleY)
scaleX
,
scaleY
1
E+UNon-uniform scale
alpha
1
E+UAlpha transparency
rotate
0
E+URotation in degrees
tint
0xffffff
E+UTint color (WebGL)
color
E+UColor array to interpolate (overrides tint)
colorEase
Ease for color interpolation
lifespan
1000
ELifetime in ms
delay
0
EDelay before visible (ms)
hold
0
EHold at end of life before dying (ms)
quantity
1
EParticles per flow cycle
accelerationX/Y
0
E+UAcceleration (px/s^2)
maxVelocityX/Y
10000
E+UMax velocity
bounce
0
E+UBounce restitution (0-1)
moveToX
,
moveToY
0
E+UTarget position (overrides angle/speed)
E = emit-only, E+U = emit + update (supports start/end, onUpdate)
所有属性均支持前文描述的灵活取值格式。
属性默认值E/U描述
x
,
y
0
E+U粒子相对于发射器的偏移量
speed
0
E径向速度(设置speedX,停用speedY)
speedX
,
speedY
0
E定向速度(设置radial=false)
angle
{min:0,max:360}
E发射角度(度)
scale
1
E+U统一缩放(设置scaleX,停用scaleY)
scaleX
,
scaleY
1
E+U非统一缩放
alpha
1
E+U透明度
rotate
0
E+U旋转角度(度)
tint
0xffffff
E+U着色颜色(WebGL)
color
E+U要插值的颜色数组(会覆盖tint)
colorEase
颜色插值的缓动方式
lifespan
1000
E粒子生命周期(毫秒)
delay
0
E粒子可见前的延迟(毫秒)
hold
0
E生命周期结束后保持可见的时长(毫秒)
quantity
1
E每个流动周期发射的粒子数量
accelerationX/Y
0
E+U加速度(像素/秒²)
maxVelocityX/Y
10000
E+U最大速度
bounce
0
E+U弹跳恢复系数(0-1)
moveToX
,
moveToY
0
E+U目标位置(会覆盖angle/speed)
E = 仅发射时生效,E+U = 发射+更新时生效(支持start/end、onUpdate)

Zone Config Properties

区域配置属性

Config KeyTypeProperties
emitZone
object or array
{ type: 'random', source: <shape> }
{ type: 'edge', source: <shape>, quantity, stepRate, yoyo, seamless, total }
deathZone
object or array
{ type: 'onEnter'|'onLeave', source: <shape> }
bounds
object
{ x, y, width, height }
or
{ x, y, w, h }
配置键类型属性
emitZone
object或array
{ type: 'random', source: <shape> }
{ type: 'edge', source: <shape>, quantity, stepRate, yoyo, seamless, total }
deathZone
object或array
{ type: 'onEnter'|'onLeave', source: <shape> }
bounds
object
{ x, y, width, height }
{ x, y, w, h }

Events

事件

All events are emitted on the
ParticleEmitter
instance itself.
EventStringCallback ArgsWhen
START
'start'
(emitter)
start()
is called and emitter begins emitting
STOP
'stop'
(emitter)
stop()
is called, or duration/stopAfter limit reached
COMPLETE
'complete'
(emitter)
Final alive particle dies after emitter has stopped
EXPLODE
'explode'
(emitter, particle)
explode()
is called
DEATH_ZONE
'deathzone'
(emitter, particle, zone)
A death zone kills a particle
js
emitter.on('stop', (emitter) => { /* stopped emitting */ });
emitter.on('complete', (emitter) => { /* all particles dead */ });
emitter.on('deathzone', (emitter, particle, zone) => { /* ... */ });
所有事件均由
ParticleEmitter
实例自身触发。
事件字符串回调参数触发时机
START
'start'
(emitter)
调用
start()
且发射器开始发射粒子时
STOP
'stop'
(emitter)
调用
stop()
,或达到duration/stopAfter限制时
COMPLETE
'complete'
(emitter)
发射器停止后,最后一个存活粒子消亡时
EXPLODE
'explode'
(emitter, particle)
调用
explode()
DEATH_ZONE
'deathzone'
(emitter, particle, zone)
消亡区域销毁粒子时
js
emitter.on('stop', (emitter) => { /* 停止发射 */ });
emitter.on('complete', (emitter) => { /* 所有粒子消亡 */ });
emitter.on('deathzone', (emitter, particle, zone) => { /* ... */ });

API Quick Reference

API快速参考

ParticleEmitter Key Methods

ParticleEmitter核心方法

Lifecycle:
start(advance?, duration?)
,
stop(kill?)
,
pause()
,
resume()
,
flow(frequency, count?, stopAfter?)
,
explode(count?, x?, y?)
,
emitParticleAt(x?, y?, count?)
,
emitParticle(count?, x?, y?)
,
fastForward(time, delta?)
.
Config:
setConfig(config)
,
updateConfig(config)
.
Following:
startFollow(target, offX?, offY?, trackVisible?)
,
stopFollow()
.
Zones:
addEmitZone(config)
,
removeEmitZone(zone)
,
clearEmitZones()
,
addDeathZone(config)
,
removeDeathZone(zone)
,
clearDeathZones()
.
Processors:
createGravityWell(config)
,
addParticleProcessor(processor)
,
removeParticleProcessor(processor)
,
getProcessors()
.
Bounds:
addParticleBounds(x, y, w, h, collideL?, collideR?, collideT?, collideB?)
.
Callbacks/Iteration:
onParticleEmit(cb, ctx?)
,
onParticleDeath(cb, ctx?)
,
killAll()
,
forEachAlive(cb, ctx?)
,
forEachDead(cb, ctx?)
.
Counts:
getAliveParticleCount()
,
getDeadParticleCount()
,
getParticleCount()
,
atLimit()
,
reserve(count)
.
Property setters:
setParticleSpeed(x, y?)
,
setParticleScale(x, y?)
,
setParticleGravity(x, y)
,
setParticleAlpha(value)
,
setParticleTint(value)
,
setParticleLifespan(value)
,
setEmitterAngle(value)
,
setQuantity(qty)
,
setFrequency(freq, qty?)
,
setRadial(value)
,
setEmitterFrame(frames, random?, qty?)
,
setAnim(anims, random?, qty?)
.
Sorting:
setSortProperty(property, ascending?)
,
setSortCallback(callback)
,
depthSort()
.
Utility:
getBounds(padding?, advance?, delta?, output?)
,
overlap(target)
.
生命周期:
start(advance?, duration?)
,
stop(kill?)
,
pause()
,
resume()
,
flow(frequency, count?, stopAfter?)
,
explode(count?, x?, y?)
,
emitParticleAt(x?, y?, count?)
,
emitParticle(count?, x?, y?)
,
fastForward(time, delta?)
.
配置:
setConfig(config)
,
updateConfig(config)
.
跟随:
startFollow(target, offX?, offY?, trackVisible?)
,
stopFollow()
.
区域:
addEmitZone(config)
,
removeEmitZone(zone)
,
clearEmitZones()
,
addDeathZone(config)
,
removeDeathZone(zone)
,
clearDeathZones()
.
处理器:
createGravityWell(config)
,
addParticleProcessor(processor)
,
removeParticleProcessor(processor)
,
getProcessors()
.
边界:
addParticleBounds(x, y, w, h, collideL?, collideR?, collideT?, collideB?)
.
回调/遍历:
onParticleEmit(cb, ctx?)
,
onParticleDeath(cb, ctx?)
,
killAll()
,
forEachAlive(cb, ctx?)
,
forEachDead(cb, ctx?)
.
计数:
getAliveParticleCount()
,
getDeadParticleCount()
,
getParticleCount()
,
atLimit()
,
reserve(count)
.
属性设置器:
setParticleSpeed(x, y?)
,
setParticleScale(x, y?)
,
setParticleGravity(x, y)
,
setParticleAlpha(value)
,
setParticleTint(value)
,
setParticleLifespan(value)
,
setEmitterAngle(value)
,
setQuantity(qty)
,
setFrequency(freq, qty?)
,
setRadial(value)
,
setEmitterFrame(frames, random?, qty?)
,
setAnim(anims, random?, qty?)
.
排序:
setSortProperty(property, ascending?)
,
setSortCallback(callback)
,
depthSort()
.
工具:
getBounds(padding?, advance?, delta?, output?)
,
overlap(target)
.

GravityWell

GravityWell

Property/MethodDescription
x
,
y
World position of the well
power
Force strength (negative to repel)
epsilon
Min distance for force calc (default 100)
gravity
Gravitational constant (default 50)
active
Enable/disable processing (inherited from ParticleProcessor)
Constructor:
new GravityWell(x, y, power, epsilon, gravity)
or
new GravityWell(config)
where config is
{ x, y, power, epsilon, gravity }
.
属性/方法描述
x
,
y
引力井的世界坐标
power
力的强度(负值表示推开粒子)
epsilon
力计算的最小距离(默认100)
gravity
引力常数(默认50)
active
启用/禁用处理器(继承自ParticleProcessor)
构造函数:
new GravityWell(x, y, power, epsilon, gravity)
new GravityWell(config)
,其中config为
{ x, y, power, epsilon, gravity }
.

Gotchas

注意事项

  • No ParticleEmitterManager: Removed in v3.60.
    this.add.particles()
    returns a
    ParticleEmitter
    directly.
  • speed
    vs
    speedX
    /
    speedY
    :
    speed
    sets speedX and deactivates speedY (radial).
    speedX
    /
    speedY
    switches to point mode (
    radial: false
    ).
  • scale
    vs
    scaleX
    /
    scaleY
    :
    scale
    applies to scaleX and deactivates scaleY. Use both for non-uniform scaling.
  • color
    overrides
    tint
    :
    They are mutually exclusive;
    color
    (array) takes priority.
  • moveToX
    /
    moveToY
    :
    Both must be set to activate. Overrides
    angle
    and
    speed
    .
  • emitting
    vs
    active
    :
    emitting: false
    = no new particles but alive ones update.
    active: false
    = entire emitter frozen.
  • stop
    vs
    complete
    :
    'stop'
    fires when emission stops.
    'complete'
    fires when the last alive particle dies.
  • frequency: 0
    :
    Means emit every frame (max rate), not "never." Use
    emitting: false
    to prevent emission.
  • frequency: -1
    :
    Puts the emitter in explode mode -- it will not flow automatically. Use
    explode()
    to emit bursts.
  • hold
    freezes particle:
    After lifespan expires,
    hold
    keeps the particle visible and frozen for the specified ms before it dies. Useful for trail/lingering effects.
  • advance
    fast-forwards:
    Pre-warms the emitter by simulating the given ms on creation, so particles are already visible on the first frame.
  • reserve(count)
    pre-allocates:
    Call
    reserve()
    or set
    reserve
    in config to pre-create particle objects upfront, avoiding GC spikes during gameplay from on-demand allocation.
  • Zone source methods: RandomZone needs
    getRandomPoint(point)
    . EdgeZone needs
    getPoints(quantity, stepRate)
    . DeathZone needs
    contains(x, y)
    .
  • Particle pool:
    maxParticles
    limits total objects (not alive count). Use
    maxAliveParticles
    for visible limit.
  • Texture required: The emitter needs a valid texture key. Use
    frame
    config for multi-frame textures.
  • 无ParticleEmitterManager: 在v3.60中已移除。
    this.add.particles()
    直接返回
    ParticleEmitter
    实例。
  • speed
    vs
    speedX
    /
    speedY
    speed
    会设置speedX并停用speedY(径向模式)。
    speedX
    /
    speedY
    会切换到点模式(
    radial: false
    )。
  • scale
    vs
    scaleX
    /
    scaleY
    scale
    会应用到scaleX并停用scaleY。如需非统一缩放,请同时使用scaleX和scaleY。
  • color
    覆盖
    tint
    二者互斥;
    color
    (数组)拥有更高优先级。
  • moveToX
    /
    moveToY
    必须同时设置才能生效。会覆盖
    angle
    speed
  • emitting
    vs
    active
    emitting: false
    表示不再发射新粒子,但存活的粒子仍会更新。
    active: false
    表示整个发射器冻结。
  • stop
    vs
    complete
    'stop'
    事件在发射停止时触发。
    'complete'
    事件在最后一个存活粒子消亡时触发。
  • frequency: 0
    表示每帧发射(最大速率),而非“永不发射”。如需阻止发射,请使用
    emitting: false
  • frequency: -1
    将发射器设为爆发模式——不会自动流动。需调用
    explode()
    来发射爆发粒子。
  • hold
    冻结粒子:
    生命周期结束后,
    hold
    会让粒子保持可见并冻结指定时长后再消亡。适用于拖尾/残留效果。
  • advance
    快进:
    创建时模拟指定时长的运行,使第一帧就可见粒子。
  • reserve(count)
    预分配:
    调用
    reserve()
    或在配置中设置
    reserve
    以提前创建粒子对象,避免游戏过程中按需分配导致的GC峰值。
  • 区域源方法: RandomZone需要
    getRandomPoint(point)
    方法。EdgeZone需要
    getPoints(quantity, stepRate)
    方法。DeathZone需要
    contains(x, y)
    方法。
  • 粒子池:
    maxParticles
    限制粒子对象总数(而非存活数量)。如需限制可见数量,请使用
    maxAliveParticles
  • 必须提供纹理: 发射器需要有效的纹理键。对于多帧纹理,请使用
    frame
    配置。

Source Files

源码文件

See
references/REFERENCE.md
for the full source file map. Key entry points:
src/gameobjects/particles/ParticleEmitter.js
(main class),
src/gameobjects/particles/Particle.js
(individual particle),
src/gameobjects/particles/zones/
(zone classes).
完整的源码文件映射请参考
references/REFERENCE.md
。核心入口文件:
src/gameobjects/particles/ParticleEmitter.js
(主类)、
src/gameobjects/particles/Particle.js
(单个粒子)、
src/gameobjects/particles/zones/
(区域类)。