Skip to content

粒子 ​

Particles2D 是粒子发射器,用来做火花、爆炸、拖尾。粒子本身不是节点,数据存在发射器里,一个发射器只有一次绘制调用。

ts
import { Particles2D, Scene, tex, v, type Vector2 } from 'sapling2d'

export class Arena extends Scene {
  static override assets = { spark: tex('spark.png'), smoke: tex('smoke.png') }

  override ready() {
    // 持续发射:跟着角色的烟(localCoords 默认 false:烟留在原地,角色跑开后形成拖尾)
    this.add(
      new Particles2D({ name: 'Smoke', texture: Arena.assets.smoke, position: v(375, 900), amount: 40, lifetime: 0.8,
        direction: -Math.PI / 2, spread: 0.3, speedMin: 40, speedMax: 80, scaleStart: 0.5, scaleEnd: 1.5, alphaEnd: 0 }),
    )
  }

  /** 刀碰刀的火花:一次性爆发,全部消失后删掉发射器。 */
  sparks(at: Vector2) {
    const fx = this.add(
      new Particles2D({ name: 'Sparks', texture: Arena.assets.spark, position: at, emitting: false, amount: 14, lifetime: 0.35,
        lifetimeRandomness: 0.4, speedMin: 250, speedMax: 500, damping: 5, scaleStart: 1, scaleEnd: 0.2, alphaEnd: 0, selfModulate: 0xffd060 }),
    )
    fx.emit()
    fx.finished.connect(() => fx.queueFree())
  }
}
ts
g.scene.sparks(v(375, 600))
g.step()
expect(g.dump()).toMatch(/Sparks \(Particles2D\) position=\(375, 600\).* particles=14/)
g.stepSeconds(0.5)
expect(g.dump()).not.toContain('Sparks') // 火花散完,发射器删掉了
expect(g.dump()).toMatch(/Smoke \(Particles2D\).*emitting=true particles=\d+/)

发射 ​

  • emitting(默认 true):持续发射,每秒 rate 个(默认 amount / lifetime)。
  • emit(n):马上爆发 n 个(默认 amount)。
  • oneShot: true:emitting 一变成 true 就爆发 amount 个,然后自动关掉。
  • amount 是同时存活的上限,到了上限不再发射。
  • 全部消失、且不再发射时发出 finished 信号,一般在这里 queueFree()。

运动和外观 ​

属性作用
direction ± spread发射方向(弧度,跟着节点的全局旋转)和散开角度(默认 π,即所有方向)
speedMin / speedMax初速度范围
gravity重力
damping每秒损失速度的比例
lifetime / lifetimeRandomness寿命和寿命的随机程度
scaleStart → scaleEnd缩放随寿命线性变化
alphaStart → alphaEnd不透明度随寿命线性变化

粒子不旋转。颜色用 selfModulate(只染粒子)或 modulate;发光的特效配合 blendMode: 'add'。

坐标 ​

默认粒子发射后留在原地,不随节点移动,适合火花、拖尾。localCoords: true 时粒子跟着节点走。

其他 ​

  • 每帧不分配内存。
  • 随机数用 tree.fxRng:测试可复现,但和游戏逻辑的 tree.rng 分开,加减粒子特效不会改变同一个 seed 的对局。
  • 时间受 timeScale 和暂停影响。
  • aliveCount 是存活的粒子数,dump() 里显示为 particles=。

MIT 许可证