@1game/solid-particles-proton
v1.23.0
Published
Solid draw-based Proton particle emitter for 1Game Engine
Readme
@1game/solid-particles-proton
@1game/solid-particles-proton 提供一个基于 draw 节点的 Solid 粒子发射器组件。
- 粒子模拟:由 drawcall/Proton(npm:
proton-engine)负责 - 粒子渲染:默认把粒子映射为 1Game
<draw data={...} />扁平圆形叶子(render.drawDataMode: 'flat'),由公开 Canvas 2D 后端的 flat batch 路径绘制(仓内实验 WebGL 后端未对用户公开) - 批次常量(整批
zIndex/ 加法混合)走particleAttrs;默认 mapper 已是池化快路径 - 契约说明:见仓库
docs/draw-data-mode.md
安装
pnpm add @1game/solid-particles-proton proton-engine基础用法
日常特效不要写 mapper。ParticlesEmitter 默认把 Proton 粒子画成圆;particleAttrs 覆盖写入每颗叶子。
import { Rate, Span, Radius, Life, Velocity, Color, Alpha } from 'proton-engine';
import { ParticlesEmitter } from '@1game/solid-particles-proton';
function FireFx() {
return (
<ParticlesEmitter
id="fire-fx"
width={600}
height={400}
emitterX={300}
emitterY={360}
particleAttrs={{
zIndex: 8,
'render.compositeMode': 'lighter',
}}
rate={new Rate(new Span(8, 16), 0.08)}
initializers={[new Radius(1, 5), new Life(0.5, 1.2), new Velocity(2, new Span(240, 300), 'polar')]}
behaviours={[new Color('#ff9f43', '#ff4757'), new Alpha(1, 0)]}
/>
);
}加法混合用 'render.compositeMode': 'lighter'(预乘 ONE, ONE)。淡出用 Proton Alpha,不要靠宿主 alpha(会进隔离层,加法被拆掉)。宿主 zIndex 是整块 draw;叶子层级用 particleAttrs.zIndex。
高定制(逃生口)
只有默认圆 + particleAttrs 不够时(换 image 叶子、非圆几何、按颗换图)才用 writeParticleToNode。必须返回 flat 叶子(无 childNodes,稳定 stableUid);particleAttrs 白名单键仍会在映射后覆盖。mapParticleToNode 为 legacy,新代码不要用。
import { ParticlesEmitter, ensurePooledDrawLeaf, writeCenteredRotationTransform, pruneNodeAttrs } from '@1game/solid-particles-proton';
const IMAGE_KEYS = new Set(['x', 'y', 'width', 'height', 'alpha', 'zIndex', 'resolvedResourceKey', 'imageFit', 'transform']);
<ParticlesEmitter
id="fx"
particleAttrs={{ zIndex: 6, 'render.compositeMode': 'lighter' }}
writeParticleToNode={(particle, index, pooled) => {
if (particle.dead) return undefined;
const node = ensurePooledDrawLeaf(pooled, `fx-${particle.id ?? index}`, 'image');
const attrs = node.attrs as Record<string, unknown>;
attrs.x = particle.p?.x ?? 0;
attrs.y = particle.p?.y ?? 0;
attrs.width = 4;
attrs.height = 4;
attrs.alpha = particle.alpha ?? 1;
attrs.resolvedResourceKey = flakeKey;
attrs.imageFit = 'contain';
writeCenteredRotationTransform(node.attrs, particle.rotation ?? 0, 4, 4);
pruneNodeAttrs(node.attrs, IMAGE_KEYS);
return node;
}}
/>;API 摘要
ParticlesEmitter
- 内部自动创建
Proton+Emitter实例 rate/initializers/behaviours/emitterX/emitterY:发射器配置(emitterX/Y挂载后变更会同步)particleAttrs:批次叶子常量(zIndex、render.compositeMode);映射结束后覆盖deafultParticles:初始粒子列表(可选)onParticlesChange/setupEmitter/getParticles/writeParticleToNode/mapParticleToNode(legacy) /updateProtonwriteParticleToNode与mapParticleToNode同时存在时以writeParticleToNode为准maxParticles:同时裁剪模拟列表与渲染映射autoStart/emitDurationrenderDrawDataMode:传给 draw 的模式提示(默认flat)
辅助函数
mapParticleToBasicNode:默认圆形叶子(含rotation→transform;兼容分配式)applyParticleToPooledBasicNode/applyParticleBatchAttrs/ensurePooledDrawLeaf/writeCenteredRotationTransform/pruneNodeAttrs:零分配写入rotationToCenteredTransform/adoptMappedParticleNodegetParticlesFromEmitter/createProtonEngineUpdater/stepProtonEngine- 注意:
proton-engine@7的proton.update()忽略入参,默认每次固定推进 ≈16.7ms;高刷下会偏快。默认与stepProtonEngine走emittersUpdate(deltaSeconds)。
- 注意:
