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

362 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 网页粒子系统 · 阶段六
> 阶段定位:**场景对象、碰撞体、路径编辑与发射器路径跟随定版**
> 完成日期: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 |
| 旋转 | 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 移动进度
路径按实际采样长度计算进度,避免不同长度曲线段使用相同参数步长后产生明显速度差异。
```text
归一化时间 = 当前时间 / 移动时长
路径进度 = 移动进度曲线(归一化时间)
```
偏移起始点限制在 `01`,用于跳过路径开头部分。反向模式从终点向起点采样,并反转移动方向角度。
### 5.3 发射器角度
| 模式 | 行为 |
|---|---|
| 固定角度 | 保持粒子系统原有根旋转 |
| 跟随移动方向 | 根据路径当前位置前后的采样点计算切线方向 |
角度会继续叠加到粒子的发射方向和锥形散布计算中。
### 5.4 跟随空间
| 空间 | 行为 |
|---|---|
| 局部空间(GEN 移动) | 移动整个发射器容器,已经出生的粒子随发射器整体移动 |
| 世界空间(粒子生成点移动) | 只移动新粒子的出生点,已经出生的粒子保留在原世界位置 |
碰撞、力场和吸附等使用世界坐标的模块同步使用当前模拟变换,避免启用路径跟随后发生坐标错位。
---
## 六、系统设置与画布辅助显示
原画布左上角的“发射点、骨骼连线、蒙皮网格”三个复选项已移动到系统设置面板。系统设置入口移动到画布左上角,并直接显示文字“系统设置”。
系统设置当前包括:
- 发射点显示,默认开启;
- 骨骼连线显示,默认关闭;
- 蒙皮网格显示,默认关闭;
- 坐标轴刻度开关;
- 刻度文字大小;
- 刻度线粗细;
- 坐标轴颜色;
- 刻度数值显示。
### 6.1 模块级重置
以下面板标题右侧统一增加“重置”按钮:
- 发射模式;
- 发射器形状;
- 粒子属性;
- 外观与资源;
- 修改器;
- 导出设置占位。
重置只恢复当前模块在 `defaultConfig()` 中的默认参数,不修改粒子系统名称、场景位置、旋转、缩放、随机种子或其他模块。外观与资源会恢复默认 `star.png` 资源,修改器会恢复全部关闭状态及默认 `trail.png` 拖尾资源。点击重置按钮不会改变面板当前的展开或折叠状态。
---
## 七、兼容性与时间轴修复
### 7.1 帧率基准
编辑器固定帧率统一为 **30 FPS**,与 Spine 默认时间基准对齐:
```text
1 秒 = 30 帧
固定模拟步长 = 1 / 30 秒
```
时间轴显示、秒数与帧数换算、拖动吸附、总帧数计算、粒子固定步长模拟和发射器路径跟随均读取同一个帧率配置,不再单独写死 60 FPS。
时间轴视口默认显示 `0120f`,相当于 4 秒可视范围;实际系统总帧数仍根据发射时长和最长粒子生命动态计算,滚轮可继续缩放显示范围。
### 7.2 粒子属性与时间轴总长度
时间轴总帧数根据各粒子系统最晚消失时间计算:
```text
总时长 = 延迟时间 + 发射持续时间 + 当前模式下的最大粒子生命
```
- 固定生命周期使用 `lifeMin`
- 随机生命周期使用 `lifeMin``lifeMax` 中的较大值;
- 多个粒子系统取最晚结束时间。
修复前固定生命周期仍按 `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. 为场景对象、路径和碰撞体补充保存、导入与导出格式。