pixijs-scene-particle-container

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese
ParticleContainer
is a specialized container for rendering hundreds to tens of thousands of lightweight sprites in a single draw call. Use it for particle effects, bullet patterns, or any case where you need a large number of similar-looking objects with minimal per-object overhead. Particles share a single base texture and have a restricted transform set; they are not full
Container
children.
Assumes familiarity with
pixijs-scene-core-concepts
.
ParticleContainer
is a special leaf in a different sense: it contains
Particle
instances in its own
particleChildren
array and rejects normal PixiJS children. Use
addParticle
, not
addChild
, and wrap the whole
ParticleContainer
in a
Container
if you need to group it with other scene objects.
The Particle API is new in v8 but is stable for production use.
ParticleContainer
是一个专用容器,可在单次绘制调用中渲染数百到数万个轻量级精灵。适用于粒子特效、弹幕图案,或任何需要大量外观相似且单对象开销极低的场景。粒子共享一个基础纹理,且变换集受限;它们并非完整的
Container
子元素。
本文假设你已熟悉
pixijs-scene-core-concepts
ParticleContainer
是一种特殊的叶节点:它在自身的
particleChildren
数组中存储
Particle
实例,且不接受普通PixiJS子元素。请使用
addParticle
而非
addChild
;若需要将其与其他场景对象分组,请将整个
ParticleContainer
包裹在
Container
中。
Particle API是v8中的新功能,但已可稳定用于生产环境。

Quick Start

快速开始

ts
const texture = await Assets.load("particle.png");

const container = new ParticleContainer({
  texture,
  boundsArea: new Rectangle(0, 0, app.screen.width, app.screen.height),
  dynamicProperties: {
    position: true,
    rotation: false,
    color: false,
  },
});

for (let i = 0; i < 10000; i++) {
  container.addParticle(
    new Particle({
      texture,
      x: Math.random() * app.screen.width,
      y: Math.random() * app.screen.height,
    }),
  );
}

app.stage.addChild(container);
Related skills:
pixijs-scene-core-concepts
(scene graph basics),
pixijs-scene-sprite
(when you need full features per object),
pixijs-assets
(shared textures, atlases),
pixijs-performance
(batching, texture optimization),
pixijs-scene-container
(wrap with other display objects).
ts
const texture = await Assets.load("particle.png");

const container = new ParticleContainer({
  texture,
  boundsArea: new Rectangle(0, 0, app.screen.width, app.screen.height),
  dynamicProperties: {
    position: true,
    rotation: false,
    color: false,
  },
});

for (let i = 0; i < 10000; i++) {
  container.addParticle(
    new Particle({
      texture,
      x: Math.random() * app.screen.width,
      y: Math.random() * app.screen.height,
    }),
  );
}

app.stage.addChild(container);
相关技能:
pixijs-scene-core-concepts
(场景图基础)、
pixijs-scene-sprite
(当你需要每个对象具备完整功能时)、
pixijs-assets
(共享纹理、图集)、
pixijs-performance
(批处理、纹理优化)、
pixijs-scene-container
(与其他显示对象一起包裹)。

Constructor options

构造函数选项

ParticleContainerOptions

ParticleContainerOptions

All
Container
options (
position
,
scale
,
tint
,
label
,
filters
,
zIndex
, etc.) are also valid here — see
skills/pixijs-scene-core-concepts/references/constructor-options.md
. Note that
children
is omitted: use
particles
instead.
OptionTypeDefaultDescription
texture
Texture
null
Shared base texture for all particles. If omitted, the container falls back to the texture of the first particle added; every particle must share the same base texture source.
particles
T[]
[]
Initial array of
Particle
(or
IParticle
) instances. Equivalent to calling
addParticle
for each, but skips per-call view updates.
dynamicProperties
ParticleProperties
{ vertex: false, position: true, rotation: false, uvs: false, color: false }
Flags for which particle attributes re-upload to the GPU every frame. Only
position
is dynamic by default; mark what you animate, leave the rest static for speed.
roundPixels
boolean
false
Rounds particle positions to the nearest pixel. Produces crisper rendering for pixel-art styles at the cost of smooth sub-pixel motion.
shader
Shader
default particle shaderReplaces the default particle shader. The custom shader must declare
aPosition
,
aUV
,
aColor
, plus any dynamic-only attributes enabled via
dynamicProperties
.
boundsArea
is inherited from
Container
but is effectively required on
ParticleContainer
: the container returns empty bounds
(0, 0, 0, 0)
by default for performance, so without
boundsArea
it is culled as invisible when culling is active and
containsPoint
always misses.
所有
Container
选项(
position
scale
tint
label
filters
zIndex
等)在此处同样有效——详见
skills/pixijs-scene-core-concepts/references/constructor-options.md
。注意
children
选项已被省略:请改用
particles
选项类型默认值说明
texture
Texture
null
所有粒子共享的基础纹理。若省略,容器将回退为第一个添加的粒子的纹理;所有粒子必须共享同一基础纹理源。
particles
T[]
[]
初始的
Particle
(或
IParticle
)实例数组。等效于为每个实例调用
addParticle
,但会跳过每次调用的视图更新。
dynamicProperties
ParticleProperties
{ vertex: false, position: true, rotation: false, uvs: false, color: false }
控制哪些粒子属性会在每一帧重新上传至GPU的标记。默认仅
position
为动态属性;请标记你需要动画的属性,其余保持静态以提升速度。
roundPixels
boolean
false
将粒子位置四舍五入到最近的像素。在像素艺术风格下能产生更清晰的渲染效果,但会牺牲平滑的亚像素运动。
shader
Shader
默认粒子着色器替换默认的粒子着色器。自定义着色器必须声明
aPosition
aUV
aColor
,以及任何通过
dynamicProperties
启用的仅动态属性。
boundsArea
继承自
Container
,但对
ParticleContainer
来说实际上是必填项:默认情况下,容器为了性能会返回空边界
(0, 0, 0, 0)
,因此如果未设置
boundsArea
,当剔除功能激活时它会被视为不可见而被剔除,且
containsPoint
始终无法命中。

ParticleOptions

ParticleOptions

Particle
is a lightweight struct, not a
Container
subclass — none of the
ContainerOptions
fields apply. The full option list:
OptionTypeDefaultDescription
texture
Texture
Required. Texture used to render this particle. All particles in the same
ParticleContainer
must share the same base texture source.
x
number
0
X position in the container's local space.
y
number
0
Y position in the container's local space.
scaleX
number
1
Horizontal scale factor.
scaleY
number
1
Vertical scale factor.
anchorX
number
0
Horizontal anchor in 0–1 range;
0
is left,
0.5
is center,
1
is right.
anchorY
number
0
Vertical anchor in 0–1 range;
0
is top,
0.5
is center,
1
is bottom.
rotation
number
0
Rotation in radians.
tint
ColorSource
0xffffff
Tint color as hex number or CSS color string. Combined with
alpha
into the internal
color
field.
alpha
number
1
Transparency (0–1). Values outside the range are clamped. Combined with
tint
into the internal
color
field.
The constructor also accepts a bare
Texture
as its sole argument (
new Particle(texture)
), which is shorthand for
new Particle({ texture })
using the defaults above.
Particle.defaultOptions
is a static object you can reassign to change defaults globally; see the "Particle creation" section below.
Particle
是一个轻量级结构体,并非
Container
的子类——
ContainerOptions
的所有字段均不适用。完整选项列表如下:
选项类型默认值说明
texture
Texture
必填项。用于渲染该粒子的纹理。同一
ParticleContainer
中的所有粒子必须共享同一基础纹理源。
x
number
0
粒子在容器局部空间中的X坐标。
y
number
0
粒子在容器局部空间中的Y坐标。
scaleX
number
1
水平缩放因子。
scaleY
number
1
垂直缩放因子。
anchorX
number
0
水平锚点,范围0–1;
0
为左侧,
0.5
为中心,
1
为右侧。
anchorY
number
0
垂直锚点,范围0–1;
0
为顶部,
0.5
为中心,
1
为底部。
rotation
number
0
旋转角度(弧度)。
tint
ColorSource
0xffffff
色调颜色,可用十六进制数或CSS颜色字符串表示。会与
alpha
合并为内部的
color
字段。
alpha
number
1
透明度(0–1)。超出范围的值会被截断。会与
tint
合并为内部的
color
字段。
构造函数也接受单个
Texture
作为唯一参数(
new Particle(texture)
),这是
new Particle({ texture })
使用上述默认值的简写形式。
Particle.defaultOptions
是一个静态对象,你可以重新赋值它来全局修改默认值;详见下方的「粒子创建」章节。

Core Patterns

核心模式

Particle creation

粒子创建

ts
const particle = new Particle({
  texture,
  x: 100,
  y: 200,
  scaleX: 0.5,
  scaleY: 0.5,
  anchorX: 0.5,
  anchorY: 0.5,
  rotation: Math.PI / 4,
  tint: 0xff0000,
  alpha: 0.8,
});

container.addParticle(particle);
Particle
is a lightweight struct with flat numeric fields:
x
,
y
,
scaleX
,
scaleY
,
anchorX
,
anchorY
,
rotation
,
color
,
texture
. It also exposes
tint
(hex/CSS color) and
alpha
(0-1) as setters that combine into the internal
color
field. No transform hierarchy, no events, no filters.
You can pass a
Texture
directly as the sole argument:
new Particle(texture)
.
Override
Particle.defaultOptions
to change defaults globally:
ts
Particle.defaultOptions = {
  ...Particle.defaultOptions,
  anchorX: 0.5,
  anchorY: 0.5,
};
ts
const particle = new Particle({
  texture,
  x: 100,
  y: 200,
  scaleX: 0.5,
  scaleY: 0.5,
  anchorX: 0.5,
  anchorY: 0.5,
  rotation: Math.PI / 4,
  tint: 0xff0000,
  alpha: 0.8,
});

container.addParticle(particle);
Particle
是一个具有扁平数字字段的轻量级结构体:
x
y
scaleX
scaleY
anchorX
anchorY
rotation
color
texture
。它还暴露了
tint
(十六进制/CSS颜色)和
alpha
(0-1)作为设置器,二者会合并为内部的
color
字段。它没有变换层级、没有事件、没有滤镜。
你可以直接传递
Texture
作为唯一参数:
new Particle(texture)
通过重写
Particle.defaultOptions
来全局修改默认值:
ts
Particle.defaultOptions = {
  ...Particle.defaultOptions,
  anchorX: 0.5,
  anchorY: 0.5,
};

Pre-populating with the particles option

使用particles选项预填充

ts
const particles = Array.from(
  { length: 10000 },
  () =>
    new Particle({
      texture,
      x: Math.random() * 800,
      y: Math.random() * 600,
    }),
);

const container = new ParticleContainer({
  texture,
  boundsArea: new Rectangle(0, 0, 800, 600),
  particles,
});
Passing
particles
in the constructor is equivalent to creating the container empty and calling
addParticle
for each one, but avoids per-call view updates.
ts
const particles = Array.from(
  { length: 10000 },
  () =>
    new Particle({
      texture,
      x: Math.random() * 800,
      y: Math.random() * 600,
    }),
);

const container = new ParticleContainer({
  texture,
  boundsArea: new Rectangle(0, 0, 800, 600),
  particles,
});
在构造函数中传入
particles
等效于创建空容器后为每个粒子调用
addParticle
,但避免了每次调用的视图更新。

Dynamic vs static properties and update()

动态与静态属性及update()

ts
const container = new ParticleContainer({
  dynamicProperties: {
    rotation: true,
  },
});
dynamicProperties
controls which particle attributes re-upload to the GPU every frame. The defaults on
ParticleContainer.defaultOptions.dynamicProperties
are:
ts
{ vertex: false, position: true, rotation: false, uvs: false, color: false }
You only need to override the properties you are animating; the rest inherit the defaults (position dynamic, everything else static). Five properties in total:
  • vertex
    : scale/anchor vertices
  • position
  • rotation
  • uvs
    : texture coordinates (for frame-swapped particles)
  • color
    : tint and alpha
Mark only what you animate; static properties are cheaper. If you change a static property at runtime, call
container.update()
to re-upload:
ts
container.particleChildren.forEach((p) => {
  p.tint = 0x00ff00;
});
container.update();
ts
const container = new ParticleContainer({
  dynamicProperties: {
    rotation: true,
  },
});
dynamicProperties
控制哪些粒子属性会在每一帧重新上传至GPU。
ParticleContainer.defaultOptions.dynamicProperties
的默认值为:
ts
{ vertex: false, position: true, rotation: false, uvs: false, color: false }
你只需重写需要动画的属性;其余属性继承默认值(位置为动态,其余为静态)。共有五个属性:
  • vertex
    :缩放/锚点顶点
  • position
    :位置
  • rotation
    :旋转
  • uvs
    :纹理坐标(用于帧切换的粒子)
  • color
    :色调与透明度
仅标记你需要动画的属性;静态属性的开销更低。如果在运行时修改了静态属性,请调用
container.update()
重新上传:
ts
container.particleChildren.forEach((p) => {
  p.tint = 0x00ff00;
});
container.update();

Batch operations on particleChildren

对particleChildren进行批量操作

ts
// Bulk add
const batch = [];
for (let i = 0; i < 5000; i++) {
  batch.push(
    new Particle({ texture, x: Math.random() * 800, y: Math.random() * 600 }),
  );
}
container.particleChildren.push(...batch);
container.update();

// Bulk remove
container.particleChildren.length = 0;
container.update();
addParticle
,
addParticleAt
,
removeParticle
,
removeParticleAt
, and
removeParticles
all trigger view updates per call. For large batch operations, direct array manipulation plus a single
update()
is faster.
ts
// 批量添加
const batch = [];
for (let i = 0; i < 5000; i++) {
  batch.push(
    new Particle({ texture, x: Math.random() * 800, y: Math.random() * 600 }),
  );
}
container.particleChildren.push(...batch);
container.update();

// 批量移除
container.particleChildren.length = 0;
container.update();
addParticle
addParticleAt
removeParticle
removeParticleAt
removeParticles
每次调用都会触发视图更新。对于大型批量操作,直接操作数组加上单次
update()
的速度更快。

Texture and shader options

纹理与着色器选项

texture
in
ParticleContainerOptions
is optional. If omitted, the container falls back to the texture of the first particle added; every subsequent particle must share the same base texture source. Set it explicitly when you want to declare the atlas up front, or when the first particle might change mid-run:
ts
const container = new ParticleContainer({ texture });
shader
lets you replace the default particle shader with any
Shader
instance. The custom shader must declare the attributes the particle pipe uploads (
aPosition
,
aUV
,
aColor
, plus any dynamic-only attributes enabled via
dynamicProperties
). Use this for custom blending math, distance-field sprites, or non-standard effects:
ts
const container = new ParticleContainer({ texture, shader: myCustomShader });
ParticleContainerOptions
中的
texture
是可选的。若省略,容器将回退为第一个添加的粒子的纹理;后续添加的所有粒子必须共享同一基础纹理源。当你想要预先声明图集,或者第一个粒子可能在运行过程中发生变化时,请显式设置它:
ts
const container = new ParticleContainer({ texture });
shader
允许你用任何
Shader
实例替换默认的粒子着色器。自定义着色器必须声明粒子管道上传的属性(
aPosition
aUV
aColor
,以及任何通过
dynamicProperties
启用的仅动态属性)。可用于自定义混合运算、距离场精灵或非标准特效:
ts
const container = new ParticleContainer({ texture, shader: myCustomShader });

Limitations

局限性

ParticleContainer
intentionally sacrifices features for speed:
  • No filters, masks, or blend modes on individual particles.
  • No nested children on particles.
  • No automatic bounds calculation.
  • All particles must share the same base texture source (atlases work; multiple unrelated textures do not).
  • Custom shaders are supported via the
    shader
    option.
ParticleContainer
为了速度刻意牺牲了部分功能:
  • 单个粒子不支持滤镜、遮罩或混合模式。
  • 粒子不支持嵌套子元素。
  • 不支持自动边界计算。
  • 所有粒子必须共享同一基础纹理源(图集可行;多个不相关的纹理不可行)。
  • 通过
    shader
    选项支持自定义着色器。

Container method migration

容器方法迁移

ParticleContainer
uses a separate child management API optimized for GPU buffer updates. The standard
Container
child methods throw when called on a
ParticleContainer
.
Standard Container methodParticleContainer equivalent
addChild(child)
addParticle(particle)
removeChild(child)
removeParticle(particle)
addChildAt(child, index)
addParticleAt(particle, index)
removeChildAt(index)
removeParticleAt(index)
removeChildren(begin, end)
removeParticles(begin, end)
getChildAt(index)
Access
container.particleChildren[index]
directly
swapChildren()
Not available
reparentChild()
Not available
ParticleContainer
使用一套独立的子元素管理API,针对GPU缓冲区更新进行了优化。标准
Container
的子元素方法在
ParticleContainer
上调用时会抛出错误。
标准Container方法ParticleContainer等效方法
addChild(child)
addParticle(particle)
removeChild(child)
removeParticle(particle)
addChildAt(child, index)
addParticleAt(particle, index)
removeChildAt(index)
removeParticleAt(index)
removeChildren(begin, end)
removeParticles(begin, end)
getChildAt(index)
直接访问
container.particleChildren[index]
swapChildren()
不可用
reparentChild()
不可用

Common Mistakes

常见错误

[CRITICAL] Adding Sprites to ParticleContainer

[严重] 向ParticleContainer添加Sprite

Wrong:
ts
const container = new ParticleContainer();
const sprite = new Sprite(texture);
container.addChild(sprite);
Correct:
ts
const container = new ParticleContainer();
const particle = new Particle(texture);
container.addParticle(particle);
ParticleContainer
does not accept
Sprite
children.
addChild
throws an error. Particles must be
Particle
instances (or any object implementing
IParticle
), added via
addParticle
. This is a complete rework from v7, where
ParticleContainer
accepted
Sprite
children.
错误示例:
ts
const container = new ParticleContainer();
const sprite = new Sprite(texture);
container.addChild(sprite);
正确示例:
ts
const container = new ParticleContainer();
const particle = new Particle(texture);
container.addParticle(particle);
ParticleContainer
不接受
Sprite
子元素。调用
addChild
会抛出错误。粒子必须是
Particle
实例(或任何实现
IParticle
的对象),并通过
addParticle
添加。这与v7版本完全不同,v7中的
ParticleContainer
接受
Sprite
子元素。

[HIGH] Not setting boundsArea on ParticleContainer

[高风险] 不为ParticleContainer设置boundsArea

Wrong:
ts
const container = new ParticleContainer();
// bounds is always (0, 0, 0, 0) — culling and hit testing fail
Correct:
ts
const container = new ParticleContainer({
  boundsArea: new Rectangle(0, 0, 800, 600),
});
ParticleContainer
returns empty bounds
(0, 0, 0, 0)
by default for performance. Without
boundsArea
, the container is culled as invisible when culling is active, and
containsPoint
always misses. Set
boundsArea
to the region your particles occupy.
错误示例:
ts
const container = new ParticleContainer();
// 边界始终为(0, 0, 0, 0) —— 剔除和点击测试会失败
正确示例:
ts
const container = new ParticleContainer({
  boundsArea: new Rectangle(0, 0, 800, 600),
});
ParticleContainer
默认返回空边界
(0, 0, 0, 0)
以提升性能。如果未设置
boundsArea
,当剔除功能激活时它会被视为不可见而被剔除,且
containsPoint
始终无法命中。请将
boundsArea
设置为粒子占据的区域。

[HIGH] Using children instead of particleChildren

[高风险] 使用children而非particleChildren

Wrong:
ts
container.addParticle(new Particle(texture));
console.log(container.children.length); // 0
Correct:
ts
container.addParticle(new Particle(texture));
console.log(container.particleChildren.length); // 1
Particles are stored in the
particleChildren
array, not
children
. The standard
Container.children
array is empty on a
ParticleContainer
. All particle enumeration, counting, and manipulation must use
particleChildren
plus the
*Particle
methods.
错误示例:
ts
container.addParticle(new Particle(texture));
console.log(container.children.length); // 0
正确示例:
ts
container.addParticle(new Particle(texture));
console.log(container.particleChildren.length); // 1
粒子存储在
particleChildren
数组中,而非
children
。标准
Container.children
数组在
ParticleContainer
上是空的。所有粒子的枚举、计数和操作都必须使用
particleChildren
加上
*Particle
方法。

[MEDIUM] Do not use ParticleContainer as a normal container

[中等风险] 不要将ParticleContainer当作普通容器使用

ParticleContainer
contains particles, not display objects. If you need to group a particle system with a background sprite or UI overlay, wrap the
ParticleContainer
itself inside a plain
Container
:
ts
const world = new Container();
world.addChild(backgroundSprite, particleContainer, uiLayer);
ParticleContainer
存储的是粒子,而非显示对象。如果你需要将粒子系统与背景精灵或UI覆盖层分组,请将
ParticleContainer
本身包裹在一个普通的
Container
中:
ts
const world = new Container();
world.addChild(backgroundSprite, particleContainer, uiLayer);

API Reference

API参考