Files
SpineParticlesWeb/Document/网页粒子系统阶段六.md
T
2026-09-02 10:45:10 +08:00

13 KiB
Raw Blame History

网页粒子系统 · 阶段六

阶段定位:场景对象、碰撞体、路径编辑与发射器路径跟随定版
完成日期:2026-08-29
工程目录:/Users/tianmokeji/Desktop/SpineParticle
技术栈:Vue 3 + TypeScript + Pinia + PixiJS 7 + Vite


一、阶段结论

阶段六完成了碰撞功能所需的场景对象基础,并把粒子系统、碰撞体和路径统一纳入同一套场景对象树。碰撞体已经参与粒子运行时计算;路径具备可视化锚点、贝塞尔手柄和预设形状编辑能力;粒子系统新增发射器路径跟随修改器。

本阶段主要完成:

  1. 统一场景对象创建入口和对象列表;
  2. 新增碰撞体对象、属性面板、画布显示和实时碰撞响应;
  3. 新增路径对象、锚点及贝塞尔手柄编辑;
  4. 新增圆形、方形、多边形和星形路径预设;
  5. 新增发射器路径跟随修改器;
  6. 支持局部空间和世界空间两种跟随方式;
  7. 整理画布左上角系统设置入口;
  8. 修复新模块与既有粒子属性、固定帧缓存和时间轴的兼容问题;
  9. 修复时间轴粒子条拖动时反复重置模拟的问题。

Spine 骨架创建入口在本阶段仅保留占位,尚未创建实际骨架对象。碰撞体面板中的“跟随轨道移动”也保留为后续碰撞体动画接口,本阶段未接入路径采样。


二、场景对象统一管理

2.1 创建入口

原编辑器顶部的“+系统”入口已合并到“场景对象”模块。场景对象标题右侧提供:

  • +粒子:创建粒子系统;
  • +碰撞:创建碰撞体;
  • +路径:创建路径;
  • +骨架Spine 骨架占位入口。

即使场景中没有粒子系统,场景对象模块仍可独立创建碰撞体或路径。

2.2 对象树

创建后的对象统一显示在场景对象树中,不再保留顶部独立的粒子系统列表。对象树支持:

  • 粒子系统、碰撞体和路径混合显示;
  • 点击对象切换当前属性面板;
  • 当前对象高亮;
  • 单独删除对象;
  • 删除当前对象后自动选择可用的回退对象。

默认对象名称使用英文编号:

对象类型 默认名称
粒子系统 ParticleSystem1
碰撞体 Collider1
路径 Path1

三、碰撞体对象

3.1 默认参数

参数 默认值
名称 Collider1
标签 Default
类型 圆形
启用 开启
X / Y 0 / 0
旋转
半径 50
椭圆 X / Y 半径 70 / 45
矩形宽 / 高 120 / 80
多边形边数 6
碰撞响应 物理
弹性 0.8
摩擦 0.3
跟随轨道移动 关闭,后续接入

3.2 类型

碰撞体支持五种类型:

  1. 圆形;
  2. 椭圆;
  3. 矩形;
  4. 多边形;
  5. 自定义。

圆形使用半径;椭圆使用 X/Y 半径;矩形、多边形和自定义形状使用宽高,多边形与自定义形状还可设置 3~16 的边数。

当前“自定义”采用可调边数的规则多边形作为运行时轮廓,为后续接入自由顶点编辑保留类型。

3.3 标签

  • 新建碰撞体默认拥有 Default 标签;
  • 点击标签可设为当前标签;
  • 点击 自动创建 Tag N
  • 标签数据归属于各碰撞体对象。

本阶段标签已完成编辑和存储,尚未作为粒子碰撞过滤条件。

3.4 碰撞响应

响应 行为
物理(弹跳/摩擦) 把粒子推出碰撞体,根据法线反射速度,并应用弹性和切向摩擦
暂停(停止不动) 粒子停留在碰撞边界,速度清零,但自身生命周期继续消耗
消失(立即销毁) 粒子进入碰撞体后立即死亡并回收到粒子池

弹性和摩擦限制在 01

  • 弹性 1 表示完全弹跳,0 表示不保留法线反弹速度;
  • 摩擦 1 表示停止切向滑动,0 表示保留切向速度。

3.5 坐标与运行时

碰撞体使用场景世界坐标。每帧把粒子局部位置和速度转换到世界空间完成碰撞检测,再把修正后的位置和速度变换回粒子系统局部空间。因此粒子系统经过位移、旋转、缩放或发射器路径跟随后,仍能与固定世界碰撞体正确交互。

原修改器面板中的全局“碰撞体开关”已移除。是否参与碰撞由每个碰撞体自己的“启用”属性控制。


四、路径对象与画布编辑

4.1 路径属性

每条路径独立保存:

  • 英文名称 PathN
  • 启用状态;
  • 对象位置和旋转;
  • 是否闭合;
  • 轨道颜色;
  • 锚点及入/出贝塞尔手柄;
  • 当前预设类型。

路径使用三次贝塞尔曲线连接相邻锚点。闭合路径会额外连接最后一个锚点与第一个锚点。

4.2 锚点操作

  • 双击空白处或曲线:新建锚点;
  • 双击锚点:删除节点;
  • 双击第二下按住拖动:新建锚点并拉出对称手柄;
  • 拖动锚点:移动节点;
  • 拖动手柄:调整曲线;
  • Shift + 拖动手柄:两侧手柄长度与方向完全对称;
  • Alt + 拖动手柄:独立控制单侧手柄;
  • Ctrl/Command + 点击或框选:加选节点;
  • Alt + 点击或框选:减选节点;
  • Alt + 单击空白处:清空选择;
  • 选中多个节点后拖动:整体移动所选节点。

路径锚点、手柄、连线和选择状态均直接绘制在画布中。

4.3 路径预设

预设 生成结果
圆形 4 个锚点和贝塞尔手柄组成的闭合圆
方形 4 个直线锚点组成的闭合方形
多边形 6 个锚点组成的闭合规则多边形
星形 10 个交替半径锚点组成的闭合星形

“应用预设”会替换当前路径锚点,“清空锚点”只清除节点,不删除路径对象。


五、发射器路径跟随

5.1 默认状态

参数 默认值
开启发射器跟随 关闭
跟随模式
跟随轨道
发射器角度模式 固定角度
移动进度曲线 0→1 线性
移动时长 2 秒
跟随空间 世界空间
移动方向 正向
偏移起始点 0

开启修改器后,跟随模式仍默认为“无”;只有主动选择“跟随轨道”并指定有效路径后,发射器才开始移动。

5.2 移动进度

路径按实际采样长度计算进度,避免不同长度曲线段使用相同参数步长后产生明显速度差异。

归一化时间 = 当前时间 / 移动时长
路径进度 = 移动进度曲线(归一化时间)

偏移起始点限制在 01,用于跳过路径开头部分。反向模式从终点向起点采样,并反转移动方向角度。

5.3 发射器角度

模式 行为
固定角度 保持粒子系统原有根旋转
跟随移动方向 根据路径当前位置前后的采样点计算切线方向

角度会继续叠加到粒子的发射方向和锥形散布计算中。

5.4 跟随空间

空间 行为
局部空间(GEN 移动) 移动整个发射器容器,已经出生的粒子随发射器整体移动
世界空间(粒子生成点移动) 只移动新粒子的出生点,已经出生的粒子保留在原世界位置

碰撞、力场和吸附等使用世界坐标的模块同步使用当前模拟变换,避免启用路径跟随后发生坐标错位。


六、系统设置与画布辅助显示

原画布左上角的“发射点、骨骼连线、蒙皮网格”三个复选项已移动到系统设置面板。系统设置入口移动到画布左上角,并直接显示文字“系统设置”。

系统设置当前包括:

  • 发射点显示,默认开启;
  • 骨骼连线显示,默认关闭;
  • 蒙皮网格显示,默认关闭;
  • 坐标轴刻度开关;
  • 刻度文字大小;
  • 刻度线粗细;
  • 坐标轴颜色;
  • 刻度数值显示。

6.1 模块级重置

以下面板标题右侧统一增加“重置”按钮:

  • 发射模式;
  • 发射器形状;
  • 粒子属性;
  • 外观与资源;
  • 修改器;
  • 导出设置占位。

重置只恢复当前模块在 defaultConfig() 中的默认参数,不修改粒子系统名称、场景位置、旋转、缩放、随机种子或其他模块。外观与资源会恢复默认 star.png 资源,修改器会恢复全部关闭状态及默认 trail.png 拖尾资源。点击重置按钮不会改变面板当前的展开或折叠状态。


七、兼容性与时间轴修复

7.1 帧率基准

编辑器固定帧率统一为 30 FPS,与 Spine 默认时间基准对齐:

1 秒 = 30 帧
固定模拟步长 = 1 / 30 秒

时间轴显示、秒数与帧数换算、拖动吸附、总帧数计算、粒子固定步长模拟和发射器路径跟随均读取同一个帧率配置,不再单独写死 60 FPS。

时间轴视口默认显示 0120f,相当于 4 秒可视范围;实际系统总帧数仍根据发射时长和最长粒子生命动态计算,滚轮可继续缩放显示范围。

7.2 粒子属性与时间轴总长度

时间轴总帧数根据各粒子系统最晚消失时间计算:

总时长 = 延迟时间 + 发射持续时间 + 当前模式下的最大粒子生命
  • 固定生命周期使用 lifeMin
  • 随机生命周期使用 lifeMinlifeMax 中的较大值;
  • 多个粒子系统取最晚结束时间。

修复前固定生命周期仍按 lifeMax 计算,时间轴可能提前循环,使生命周期、速度、缩放等参数看起来没有生效。

7.3 时间轴粒子条语义

时间轴粒子条使用一个延迟段和两层叠加色条:

  1. 左侧空白:发射延迟 delay
  2. 红色底条:整个粒子系统仍有粒子存在的总时长,不可直接缩放;
  3. 绿色覆盖层:持续发射时长 duration,仅持续模式显示,可拖动。

持续发射时长默认 1 秒,即 30f;拖动绿色层到 60f 表示持续发射 2 秒。持续模式下,红色底条长度为“绿色发射时长 + 最长粒子生命”,绿色覆盖红色底条的前半段,停止发射后露出的红色尾段表示剩余粒子继续存活的时间。因此红色底条一定比绿色层长。

爆发模式没有持续发射窗口,因此不显示绿色覆盖层,红色底条长度就是最长粒子生命。

红色生命段根据粒子属性模式自动计算:固定模式使用固定生命值,随机模式使用上下限中的较大值。用户修改生命参数后,红色段和总帧数同步更新。

拖动整个叠加条仍用于修改发射延迟。持续发射的最短时长为 1 帧。

7.4 拖动重算修复

修复前,鼠标每次移动都会直接写入配置,触发固定帧缓存清空和粒子模拟重置,造成粒子跳动、数量异常或短暂停止。

现在的处理流程为:

  1. 按下并拖动时只更新本地条带预览;
  2. 粒子运行时保持当前模拟,不反复清空;
  3. 松开鼠标后一次性提交最终值;
  4. 固定帧缓存只重建一次;
  5. 取消拖动不修改配置;
  6. 拖长操作不再被修改前的总帧数错误限制。

切换持续/爆发模式不再承担“恢复异常状态”的作用;模式切换仅按当前配置正常重新模拟。


八、数据与迁移

粒子系统配置新增发射器跟随字段,旧配置通过 ensureEmitterConfig() 自动补齐默认值:

  • emitterFollow
  • emitterFollowMode
  • emitterFollowPathId
  • emitterAngleMode
  • emitterFollowCurve
  • emitterFollowDuration
  • emitterFollowSpace
  • emitterFollowDirection
  • emitterFollowOffset

碰撞体和路径存储在 Pinia 场景状态中,和粒子系统共同参与配置变化监听。对象、路径锚点或碰撞参数改变后会清空旧固定帧并从第 0 帧重新生成。


九、验证结果

本阶段完成以下验证:

  • 粒子系统、碰撞体和路径的创建、选择、删除与英文默认命名;
  • 圆形、椭圆、矩形和规则多边形碰撞检测;
  • 物理、暂停和销毁三种碰撞响应;
  • 路径预设、锚点新增删除、多选移动和手柄调整;
  • 发射器跟随默认“无”及有效路径选择;
  • 30 FPS 时间基准,确认 1 秒对应 30 帧;
  • 正向/反向、固定角度/移动方向;
  • 局部空间和世界空间跟随;
  • 路径跟随与粒子初始生命周期、速度、缩放、旋转的组合;
  • 固定生命周期与时间轴总帧数联动;
  • 时间轴延迟拖动和持续时间缩放只在松手后重建缓存;
  • 各模块重置按钮的默认值恢复与面板展开状态保持;
  • 页面运行无可见错误;
  • npm run build 生产构建通过。

十、阶段七建议

  1. 实现碰撞体自由顶点编辑,使“自定义”类型拥有独立轮廓;
  2. 把碰撞标签接入粒子系统过滤规则;
  3. 实现碰撞体跟随路径移动;
  4. 支持路径循环、往返和超出移动时长后的行为设置;
  5. 增加碰撞事件输出,为音效、子粒子或动画触发提供接口;
  6. 开始接入 Spine 骨架场景对象和骨架资源管理;
  7. 为场景对象、路径和碰撞体补充保存、导入与导出格式。