particles
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseParticle 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:
Related skills: ../sprites-and-images/SKILL.md, ../loading-assets/SKILL.md
src/gameobjects/particles/在Phaser 4中创建和控制粒子特效——包括ParticleEmitter的创建与配置、发射器操作(值格式)、引力井、发射与消亡区域、流动模式vs爆发模式、跟随游戏对象以及粒子回调。
核心源码路径:
相关技能: ../sprites-and-images/SKILL.md, ../loading-assets/SKILL.md
src/gameobjects/particles/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 oncejs
// 在场景的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
ParticleEmitterGameObjectthis.add.particles()ParticleEmitterFactory 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 , , , , , , etc.
setPosition()setScale()setDepth()setBlendMode()setMask()setScrollFactor()ParticleEmitterGameObjectthis.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: , , , , , , , , , (total ms), (remaining ms), (0-1 normalized), , , . Particles are pooled internally -- you never create them manually.
xyvelocityX/YaccelerationX/YscaleX/YalphaanglerotationtintlifelifeCurrentlifeTbouncedelayCurrentholdCurrent由发射器拥有的轻量级对象。核心属性:、、、、、、、、、(总时长,毫秒)、(剩余时长,毫秒)、(0-1归一化值)、、、。粒子在内部被池化——你永远不需要手动创建它们。
xyvelocityX/YaccelerationX/YscaleX/YalphaanglerotationtintlifelifeCurrentlifeTbouncedelayCurrentholdCurrentEmitterOp 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 shorthandEmit-only (no onUpdate): , , , , , , .
Emit + Update (support start/end, onUpdate): , , , , , , , , , .
angledelayholdlifespanquantityspeedXspeedYaccelerationX/YalphabouncemaxVelocityX/YmoveToX/YrotatescaleX/Ytintxy大多数配置属性(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):、、、、、、。
发射+更新时生效(支持start/end、onUpdate):、、、、、、、、、。
angledelayholdlifespanquantityspeedXspeedYaccelerationX/YalphabouncemaxVelocityX/YmoveToX/YrotatescaleX/YtintxyFlow vs Explode (Burst)
流动模式 vs 爆发模式(Burst)
Flow mode (): emits particles every ms. Default is (every frame) with .
frequency >= 0quantityfrequencyfrequency: 0emitting: trueExplode mode (): emits a batch all at once, then stops.
frequency = -1js
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 >= 0frequencyquantityfrequency: 0emitting: true爆发模式():一次性发射一批粒子,然后停止。
frequency = -1js
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 property interpolates through an array of colors over particle lifetime (overrides ):
colortintjs
this.add.particles(400, 300, 'spark', {
lifespan: 2000, speed: 100, scale: { start: 0.5, end: 0 },
color: [0xfacc22, 0xf89800, 0xf83600, 0x9f0404], colorEase: 'quad.out'
});colortintjs
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 lifetimejs
this.add.particles(400, 300, 'spark', { tint: 0xff0000 }); // 静态着色
this.add.particles(400, 300, 'spark', { tint: { start: 0xffffff, end: 0xff0000 } }); // 生命周期内渐变Gravity Wells
引力井
A applies inverse-square gravitational force, pulling (or repelling with negative ) particles toward a point.
GravityWellpowerjs
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);GravityWellpowerjs
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 spawns particles at random positions within a shape. The source must have a method -- all Phaser geometry classes (Circle, Ellipse, Rectangle, Triangle, Polygon, Line) support this, or provide a custom source:
RandomZonegetRandomPoint(point)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;
}
}
});RandomZonegetRandomPoint(point)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 places particles sequentially along shape edges. The source must have a method. Curves, Paths, and all geometry shapes support this:
EdgeZonegetPoints(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, // 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 or call multiple times. Zones iterate in sequence. The property controls how many particles emit before rotating to the next zone (-1 = never rotate).
emitZoneaddEmitZone()totaljs
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) }
]
});EdgeZonegetPoints(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 });多个发射区域: 向传入数组,或多次调用。区域会按顺序循环使用。属性控制发射多少个粒子后切换到下一个区域(-1表示永不切换)。
emitZoneaddEmitZone()totaljs
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 kills particles when they enter (or leave) a region. The source must have a method.
DeathZonecontains(x, y)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 }
});DeathZonecontains(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.yjs
this.add.particles(400, 300, 'spark', { sortProperty: 'y', sortOrderAsc: true });
// 或者:sortCallback: (a, b) => a.y - b.yCustom Particle Processor
自定义粒子处理器
Extend to apply custom per-particle logic each frame. Implement :
ParticleProcessorupdate(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));继承以实现每帧自定义粒子逻辑。实现方法:
ParticleProcessorupdate(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 and override for per-particle behavior. Set via in config:
ParticleupdateparticleClassjs
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
});继承并覆盖方法以实现粒子自定义行为。通过配置中的设置:
ParticleupdateparticleClassjs
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 -- 简单属性
| Property | Type | Default | Description |
|---|---|---|---|
| boolean | | False = emitter does not update at all |
| boolean | | False = no new particles (alive ones still update) |
| string/number | | Blend mode for rendering |
| number | | ms between flow cycles; 0 = every frame; -1 = explode |
| number | | Gravity in px/s^2 |
| number | | Hard limit on total particle objects (0 = unlimited) |
| number | | Max alive particles at once (0 = unlimited) |
| number | | Auto-stop after ms (0 = forever) |
| number | | Auto-stop after N particles emitted (0 = unlimited) |
| number | | Fast-forward on creation (ms) |
| boolean | | True = speed+angle; false = speedX/speedY |
| boolean | | New particles render on top |
| number | | Time multiplier for updates |
| Vector2Like | | Object to follow |
| Vector2Like | Offset from follow target | |
| boolean | | Match follow target's visibility |
| number | Pre-allocate particle objects | |
| function | | Custom particle class |
| string | Particle property to sort by | |
| boolean | Sort ascending if true |
| 属性 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| boolean | | 设为false时,发射器完全不更新 |
| boolean | | 设为false时,不再发射新粒子(存活的粒子仍会更新) |
| string/number | | 渲染混合模式 |
| number | | 流动周期间隔(毫秒);0表示每帧发射;-1表示爆发模式 |
| number | | 重力加速度(像素/秒²) |
| number | | 粒子对象总数上限(0表示无限制) |
| number | | 同时存活的粒子数量上限(0表示无限制) |
| number | | 自动停止前的持续时长(毫秒);0表示永久 |
| number | | 自动停止前发射的粒子总数;0表示无限制 |
| number | | 创建时快进的时长(毫秒) |
| boolean | | 设为true时使用speed+angle;设为false时使用speedX/speedY |
| boolean | | 新粒子渲染在最上层 |
| number | | 更新的时间乘数 |
| Vector2Like | | 要跟随的对象 |
| Vector2Like | 跟随目标的偏移量 | |
| boolean | | 是否匹配跟随目标的可见性 |
| number | 预分配的粒子对象数量 | |
| function | | 自定义粒子类 |
| string | 用于排序的粒子属性 | |
| boolean | 设为true时升序排序 |
ParticleEmitterConfig -- EmitterOp Properties
ParticleEmitterConfig -- 发射器操作属性
All accept the flexible value formats described above.
| Property | Default | E/U | Description |
|---|---|---|---|
| | E+U | Particle offset from emitter |
| | E | Radial speed (sets speedX, deactivates speedY) |
| | E | Directional speed (sets radial=false) |
| | E | Emission angle in degrees |
| | E+U | Uniform scale (sets scaleX, deactivates scaleY) |
| | E+U | Non-uniform scale |
| | E+U | Alpha transparency |
| | E+U | Rotation in degrees |
| | E+U | Tint color (WebGL) |
| E+U | Color array to interpolate (overrides tint) | |
| Ease for color interpolation | ||
| | E | Lifetime in ms |
| | E | Delay before visible (ms) |
| | E | Hold at end of life before dying (ms) |
| | E | Particles per flow cycle |
| | E+U | Acceleration (px/s^2) |
| | E+U | Max velocity |
| | E+U | Bounce restitution (0-1) |
| | E+U | Target position (overrides angle/speed) |
E = emit-only, E+U = emit + update (supports start/end, onUpdate)
所有属性均支持前文描述的灵活取值格式。
| 属性 | 默认值 | E/U | 描述 |
|---|---|---|---|
| | E+U | 粒子相对于发射器的偏移量 |
| | E | 径向速度(设置speedX,停用speedY) |
| | E | 定向速度(设置radial=false) |
| | E | 发射角度(度) |
| | E+U | 统一缩放(设置scaleX,停用scaleY) |
| | E+U | 非统一缩放 |
| | E+U | 透明度 |
| | E+U | 旋转角度(度) |
| | E+U | 着色颜色(WebGL) |
| E+U | 要插值的颜色数组(会覆盖tint) | |
| 颜色插值的缓动方式 | ||
| | E | 粒子生命周期(毫秒) |
| | E | 粒子可见前的延迟(毫秒) |
| | E | 生命周期结束后保持可见的时长(毫秒) |
| | E | 每个流动周期发射的粒子数量 |
| | E+U | 加速度(像素/秒²) |
| | E+U | 最大速度 |
| | E+U | 弹跳恢复系数(0-1) |
| | E+U | 目标位置(会覆盖angle/speed) |
E = 仅发射时生效,E+U = 发射+更新时生效(支持start/end、onUpdate)
Zone Config Properties
区域配置属性
| Config Key | Type | Properties |
|---|---|---|
| object or array | |
| ||
| object or array | |
| object | |
| 配置键 | 类型 | 属性 |
|---|---|---|
| object或array | |
| ||
| object或array | |
| object | |
Events
事件
All events are emitted on the instance itself.
ParticleEmitter| Event | String | Callback Args | When |
|---|---|---|---|
| | | |
| | | |
| | | Final alive particle dies after emitter has stopped |
| | | |
| | | 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| 事件 | 字符串 | 回调参数 | 触发时机 |
|---|---|---|---|
| | | 调用 |
| | | 调用 |
| | | 发射器停止后,最后一个存活粒子消亡时 |
| | | 调用 |
| | | 消亡区域销毁粒子时 |
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/Method | Description |
|---|---|
| World position of the well |
| Force strength (negative to repel) |
| Min distance for force calc (default 100) |
| Gravitational constant (default 50) |
| Enable/disable processing (inherited from ParticleProcessor) |
Constructor: or where config is .
new GravityWell(x, y, power, epsilon, gravity)new GravityWell(config){ x, y, power, epsilon, gravity }| 属性/方法 | 描述 |
|---|---|
| 引力井的世界坐标 |
| 力的强度(负值表示推开粒子) |
| 力计算的最小距离(默认100) |
| 引力常数(默认50) |
| 启用/禁用处理器(继承自ParticleProcessor) |
构造函数: 或 ,其中config为.
new GravityWell(x, y, power, epsilon, gravity)new GravityWell(config){ x, y, power, epsilon, gravity }Gotchas
注意事项
- No ParticleEmitterManager: Removed in v3.60. returns a
this.add.particles()directly.ParticleEmitter - vs
speed/speedX:speedYsets speedX and deactivates speedY (radial).speed/speedXswitches to point mode (speedY).radial: false - vs
scale/scaleX:scaleYapplies to scaleX and deactivates scaleY. Use both for non-uniform scaling.scale - overrides
color: They are mutually exclusive;tint(array) takes priority.color - /
moveToX: Both must be set to activate. OverridesmoveToYandangle.speed - vs
emitting:active= no new particles but alive ones update.emitting: false= entire emitter frozen.active: false - vs
stop:completefires when emission stops.'stop'fires when the last alive particle dies.'complete' - : Means emit every frame (max rate), not "never." Use
frequency: 0to prevent emission.emitting: false - : Puts the emitter in explode mode -- it will not flow automatically. Use
frequency: -1to emit bursts.explode() - freezes particle: After lifespan expires,
holdkeeps the particle visible and frozen for the specified ms before it dies. Useful for trail/lingering effects.hold - fast-forwards: Pre-warms the emitter by simulating the given ms on creation, so particles are already visible on the first frame.
advance - pre-allocates: Call
reserve(count)or setreserve()in config to pre-create particle objects upfront, avoiding GC spikes during gameplay from on-demand allocation.reserve - Zone source methods: RandomZone needs . EdgeZone needs
getRandomPoint(point). DeathZone needsgetPoints(quantity, stepRate).contains(x, y) - Particle pool: limits total objects (not alive count). Use
maxParticlesfor visible limit.maxAliveParticles - Texture required: The emitter needs a valid texture key. Use config for multi-frame textures.
frame
- 无ParticleEmitterManager: 在v3.60中已移除。直接返回
this.add.particles()实例。ParticleEmitter - vs
speed/speedX:speedY会设置speedX并停用speedY(径向模式)。speed/speedX会切换到点模式(speedY)。radial: false - vs
scale/scaleX:scaleY会应用到scaleX并停用scaleY。如需非统一缩放,请同时使用scaleX和scaleY。scale - 覆盖
color: 二者互斥;tint(数组)拥有更高优先级。color - /
moveToX: 必须同时设置才能生效。会覆盖moveToY和angle。speed - vs
emitting:active表示不再发射新粒子,但存活的粒子仍会更新。emitting: false表示整个发射器冻结。active: false - vs
stop:complete事件在发射停止时触发。'stop'事件在最后一个存活粒子消亡时触发。'complete' - : 表示每帧发射(最大速率),而非“永不发射”。如需阻止发射,请使用
frequency: 0。emitting: false - : 将发射器设为爆发模式——不会自动流动。需调用
frequency: -1来发射爆发粒子。explode() - 冻结粒子: 生命周期结束后,
hold会让粒子保持可见并冻结指定时长后再消亡。适用于拖尾/残留效果。hold - 快进: 创建时模拟指定时长的运行,使第一帧就可见粒子。
advance - 预分配: 调用
reserve(count)或在配置中设置reserve()以提前创建粒子对象,避免游戏过程中按需分配导致的GC峰值。reserve - 区域源方法: RandomZone需要方法。EdgeZone需要
getRandomPoint(point)方法。DeathZone需要getPoints(quantity, stepRate)方法。contains(x, y) - 粒子池: 限制粒子对象总数(而非存活数量)。如需限制可见数量,请使用
maxParticles。maxAliveParticles - 必须提供纹理: 发射器需要有效的纹理键。对于多帧纹理,请使用配置。
frame
Source Files
源码文件
See for the full source file map. Key entry points: (main class), (individual particle), (zone classes).
references/REFERENCE.mdsrc/gameobjects/particles/ParticleEmitter.jssrc/gameobjects/particles/Particle.jssrc/gameobjects/particles/zones/完整的源码文件映射请参考。核心入口文件:(主类)、(单个粒子)、(区域类)。
references/REFERENCE.mdsrc/gameobjects/particles/ParticleEmitter.jssrc/gameobjects/particles/Particle.jssrc/gameobjects/particles/zones/