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

369 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.
# 网页粒子系统 · 阶段七
> 阶段定位:**Spine 4.2 骨架资源接入、统一场景变换与碰撞体路径跟随定版**
> 完成日期:2026-08-29
> 工程目录:`/Users/tianmokeji/Desktop/SpineParticle`
> 技术栈:Vue 3 + TypeScript + Pinia + PixiJS 7 + Spine Runtime 4.2 + Vite
---
## 一、阶段结论
阶段七完成了 Spine 骨架场景对象的第一版完整接入,并补齐了时间轴、场景变换和碰撞体路径跟随能力。Spine 资源现在可以离线加载、显示、选择动画、查看骨骼层级,并与粒子系统共同受统一的 30 FPS 时间轴控制。
本阶段主要完成:
1. 接入 Spine 官方 4.2 PixiJS 7 运行时并离线落盘;
2. 实现 Spine 骨架场景对象及独立属性面板;
3. 支持 JSON、SKEL、Atlas 和多张纹理资源加载;
4. 自动读取动画列表、动画时长和骨骼层级;
5. Spine 动画关闭自身循环,改由编辑器时间轴统一驱动;
6. 时间轴增加紫色 Spine 动画条和逐帧控制按钮;
7. 修复动画按浏览器刷新次数推进导致的播放过快问题;
8. 统一画布变换工具,使其作用于场景树当前选中的对象;
9. 为碰撞体和路径补充缩放变换;
10. 实现碰撞体沿路径移动、速度曲线和方向跟随;
11. 统一“路径”术语,移除重复的移动轨迹显示开关;
12. 完成旧场景字段补齐和热更新兼容处理。
---
## 二、Spine 官方运行时接入
### 2.1 运行时来源
项目使用 Spine 官方仓库中的 4.2 兼容版本:
| 项目 | 内容 |
|---|---|
| 官方仓库 | `https://github.com/EsotericSoftware/spine-runtimes` |
| 兼容分支 | `4.2` |
| 固定提交 | `b81e5a58ed38704aee4f866f0e0ac672623ce914` |
| `spine-core` | `4.2.119` |
| `spine-pixi-v7` | `4.2.119` |
| 渲染目标 | PixiJS 7 |
运行时代码放置在 `vendor/spine/`,通过 `file:` 依赖接入:
```text
@esotericsoftware/spine-core -> vendor/spine/spine-core
@esotericsoftware/spine-pixi-v7 -> vendor/spine/spine-pixi-v7
```
因此项目构建时不需要从 npm 在线下载 Spine 运行时代码。版本来源、提交号和许可提示记录在 `vendor/spine/SOURCE.md`,官方许可证保存在同目录中。
### 2.2 代码拆分
Spine 功能没有继续堆叠到主面板和主画布文件中,而是拆分为:
| 文件 | 职责 |
|---|---|
| `spineTypes.ts` | Spine 场景对象、动画和骨骼元数据类型 |
| `spineAssetLoader.ts` | 读取骨架、Atlas 和纹理并生成 SkeletonData |
| `spineAssetRegistry.ts` | 管理运行时资源和纹理释放 |
| `SpineRuntimeLayer.ts` | 创建 Spine 显示对象并按编辑器帧同步动画 |
| `SpineObjectPanel.vue` | 资源选择、属性、动画列表和层级树界面 |
这种拆分让主粒子系统逻辑与第三方骨架运行时保持边界,便于后续增加插槽、皮肤、混合和导出功能。
---
## 三、Spine 场景对象
### 3.1 创建与默认状态
点击场景对象模块中的 `+骨架` 会创建一个 Spine 对象,并自动成为当前选中对象。
| 参数 | 默认值 |
|---|---:|
| 名称 | `SpineSkeleton1` |
| 启用 | 开启 |
| X / Y | 0 / 0 |
| 旋转 | 0° |
| Scale X / Y | 1 / 1 |
| 开始时间 | 0 秒 |
| 资源状态 | 未加载 |
| 当前动画 | 无 |
Spine 对象与粒子系统、碰撞体和路径统一显示在场景对象树中,支持选择和删除。删除对象时会同步释放已注册的 Spine 资源和纹理引用。
### 3.2 支持的资源
加载一套 Spine 资源时需要选择:
- 骨架数据:`.json``.skel`
- 图集描述:`.atlas`
- 纹理图片:`.png``.jpg``.jpeg``.webp`,允许多选;
- 兼容文件选择器中的 `.wepb` 拼写。
加载器按 Atlas 页面的文件名匹配所选纹理。如果 Atlas 引用了未选择的纹理,会给出明确错误,不会创建不完整的骨架对象。
### 3.3 测试资源
项目 `public/spine/` 中的 Spine 4.2 测试资源用于本阶段验证:
- `bingo.json`
- `bingo.atlas`
- `bingo.png`
- `bingo_2.png`
测试覆盖了 JSON 骨架、多纹理 Atlas、动画列表读取、画布渲染和骨骼层级展示。
---
## 四、动画与骨骼层级
### 4.1 动画列表
资源加载成功后,面板会从 SkeletonData 中读取全部动画:
- 显示动画名称;
- 显示真实动画时长,单位为秒;
- 支持选择“无”或任意动画;
- 默认选择资源中的第一个动画;
- 切换动画后重新计算时间轴总长度并回到第 0 帧。
Spine 动画自身不循环播放。动画到达末尾后停留在末帧,是否重新从头播放由编辑器总时间轴的循环按钮决定。
### 4.2 骨骼层级树
加载成功后同时读取骨骼名称、父级关系和深度,按层级显示为树结构。
层级树支持:
- 点击父骨骼前的箭头折叠或展开子级;
- “全部折叠”和“全部展开”;
- 折叠父级后隐藏其全部后代;
- 长层级树在固定高度区域内滚动。
该树当前用于查看资源结构,尚未提供骨骼选择、单骨骼变换或插槽编辑。
### 4.3 Spine 资源显示设置
原属性面板中容易误解的“启用骨架显示”已改为系统设置中的“启用 Spine 资源显示”。
- 已加载包含动画的 Spine 资源时,可以全局显示或隐藏 Spine 资源;
- 没有可用 Spine 动画时,该设置置灰;
- 该开关只控制画布中的 Spine 资源,不影响编辑器自身的粒子拖尾骨骼、骨骼连线或蒙皮网格调试显示;
- 对象自身的 `enabled` 状态仍会独立参与最终可见性判断。
---
## 五、统一时间轴
### 5.1 真实时间驱动
时间轴继续使用统一的 **30 FPS** 基准:
```text
1 秒 = 30 帧
当前动画时间 = 当前帧 / 30 - Spine 开始时间
```
修复前,Spine 动画会在浏览器每次刷新画面时前进一帧。高刷新率屏幕上动画会明显快于 Spine 编辑器中的同一动画。
现在使用实际经过时间累积,并按 `1/30` 秒的固定步长推进显示帧。浏览器刷新率只影响画面刷新平滑度,不再改变动画播放速度。
### 5.2 Spine 紫色动画条
选择有效 Spine 动画后,时间轴新增紫色动画条:
- 条带长度来自 Spine 动画的真实时长;
- 长度不可拖动修改;
- 整条可以左右拖动;
- 左侧空白表示延迟播放时间;
- 拖动以 1 帧为单位吸附;
- 没有动画数据或当前动画为“无”时不显示。
Spine 动画、粒子系统和碰撞体路径移动共同参与总时间轴长度计算:
```text
总时长 = max(
粒子系统最晚消失时间,
Spine 开始时间 + Spine 动画时长,
碰撞体路径移动时长
)
```
### 5.3 播放控制
时间轴控制区现在包括:
| 控制 | 行为 |
|---|---|
| 播放 / 暂停 | 切换整体时间轴播放状态 |
| 回到第一帧 | 跳转到第 0 帧 |
| 前一帧 | 自动暂停并后退 1 帧 |
| 后一帧 | 自动暂停并前进 1 帧 |
| 移动到最后一帧 | 自动暂停并跳转到最后帧 |
| 循环 | 控制整体时间轴到达末尾后的行为 |
这些操作统一影响粒子模拟、Spine 动画和碰撞体路径移动。
---
## 六、场景对象变换统一
### 6.1 当前选中对象
画布左上角的位移、旋转和缩放工具不再固定操作粒子系统,而是读取场景树中的当前选中对象。
支持的对象包括:
- 粒子系统;
- 碰撞体;
- 路径;
- Spine 骨架。
选择 Spine 对象后,变换工具只修改该 Spine 对象;选择碰撞体或路径后,同样只影响选中对象。
### 6.2 缩放补齐
碰撞体新增 `scaleX``scaleY`,路径继续使用独立的 `scaleX``scaleY`。两类对象均可通过属性面板或画布缩放工具修改。
路径的位移、旋转和缩放会同时作用于:
- 路径曲线显示;
- 锚点和贝塞尔手柄;
- 发射器路径采样;
- 碰撞体路径跟随。
碰撞体缩放同时影响画布轮廓和实际粒子碰撞计算。
---
## 七、碰撞体路径跟随
阶段六预留的“跟随路径移动”在本阶段完成运行时实现。
### 7.1 默认参数
| 参数 | 默认值 |
|---|---:|
| 跟随路径移动 | 关闭 |
| 目标路径 | 未选择 |
| 移动时长 | 2 秒 |
| 曲线模式 | 跟随导出 |
| 移动进度曲线 | 0→1 线性 |
| 方向沿路径 | 关闭 |
只有开启跟随并选择一条已启用且包含锚点的路径后,碰撞体才会开始移动。无效或已删除的目标路径不会改变碰撞体原始位置。
### 7.2 移动计算
```text
归一化时间 = clamp(当前时间 / 移动时长, 0, 1)
路径进度 = 移动进度曲线(归一化时间)
碰撞体位置 = 路径按长度采样(路径进度)
```
路径采样会考虑路径对象自身的位移、旋转和缩放。每段三次贝塞尔曲线先离散采样并累计实际距离,再按总长度查找位置,减少不同曲线段参数长度不一致造成的明显速度变化。
面板提供三种曲线模式:
- 跟随导出;
- 线性;
- 贝塞尔。
曲线编辑器横轴表示实时除以移动时长,纵轴表示路径进度。到达移动时长后,碰撞体停留在路径终点;编辑器时间轴循环时再从起点开始。
### 7.3 方向沿路径
“方向沿路径”默认关闭:
- 关闭时,碰撞体移动过程中保持自己的旋转值;
- 开启时,根据路径当前位置前后采样点计算切线方向;
- 碰撞体属性中的旋转值作为附加角度叠加,可继续微调朝向。
圆形碰撞体视觉上不容易观察旋转变化,矩形、椭圆和多边形更适合检查该功能。
### 7.4 碰撞运行时
路径跟随不仅改变画布上的碰撞体预览位置,也会把同一份动态位置和旋转传给粒子碰撞检测。因此粒子会与移动中的碰撞体发生真实交互,物理、暂停和销毁三种响应保持有效。
运行时使用预览副本计算动态位置,不会持续覆盖碰撞体存储的基础 X、Y 和旋转值。关闭跟随后,碰撞体会恢复到属性面板中设置的基础变换。
路径对象本身始终在画布显示,因此移除了重复的“显示移动轨迹线”开关和额外轨迹覆盖层。
---
## 八、术语与兼容性
### 8.1 路径术语统一
用于贝塞尔对象和跟随功能的界面术语统一为“路径”:
- 跟随路径移动;
- 目标路径;
- 路径进度;
- 路径名称;
- 闭合路径;
- 路径颜色;
- 发射器跟随路径。
发射器形状中的“轨道”仍表示粒子发射形状 `orbit`,不是场景路径对象,因此保留原名称。
### 8.2 旧数据补齐
旧场景或热更新状态中的碰撞体可能缺少路径跟随字段。面板会即时补齐:
- 目标路径;
- 移动时长;
- 曲线模式;
- 移动进度曲线;
- 方向沿路径。
曲线组件同时提供空值回退,避免旧数据加载或热更新瞬间因曲线为空导致界面渲染失败。
---
## 九、验证结果
本阶段完成以下验证:
- Spine 官方 4.2.119 本地运行时依赖和生产构建;
- JSON、Atlas 和两张 PNG 测试资源加载;
- 动画名称、真实时长和骨骼层级读取;
- Spine 动画非循环播放及末帧保持;
- 30 FPS 真实时间推进,不受浏览器刷新率影响;
- 紫色 Spine 时间轴条长度和开始时间拖动;
- 前一帧、后一帧和最后一帧自动暂停;
- 骨骼层级单节点折叠和全部折叠;
- Spine 资源全局显示开关和无动画时置灰;
- 当前选中粒子、碰撞体、路径和 Spine 对象的画布变换;
- 碰撞体和路径缩放与运行时表现同步;
- 碰撞体目标路径、移动时长、进度曲线和方向开关;
- 移动碰撞体参与实际粒子碰撞;
- 路径术语统一及重复轨迹开关移除;
- 旧碰撞体字段和曲线空值兼容;
- 页面面板交互检查;
- `npm run build` 生产构建通过;
- `git diff --check` 通过。
构建仍有 Vite 对主产物体积超过 500 kB 的提示,不影响当前功能和构建结果,后续可通过按模块动态加载进一步优化。
---
## 十、当前限制
1. Spine 资源通过本地文件选择器加载,刷新页面后需要重新选择,尚未纳入工程保存格式;
2. Spine 层级树当前只读,不能编辑骨骼、插槽、皮肤或约束;
3. Spine 动画尚未支持混合、播放速度、反向和多轨道叠加;
4. `.skel` 已接入官方二进制解析器,但本阶段主要使用 JSON 测试资源验证;
5. 碰撞体路径跟随当前为单次起点到终点,尚未提供往返或独立循环模式;
6. 自定义碰撞体仍使用规则多边形轮廓,尚未接入自由顶点编辑;
7. 场景对象和资源尚未形成完整的保存、导入和导出格式。
---
## 十一、阶段八建议
1. 建立场景工程保存格式,持久化粒子、路径、碰撞体和 Spine 对象配置;
2. 将 Spine 资源复制到工程资源目录,支持刷新后自动恢复;
3. 增加 Spine 皮肤、插槽、混合时长和播放速度控制;
4. 为碰撞体路径跟随增加循环、往返、反向和结束行为;
5. 实现碰撞标签过滤和碰撞事件输出;
6. 实现自定义碰撞体自由顶点编辑;
7. 对 Spine 和曲线编辑器进行动态加载,降低主包体积;
8. 建立可复现的场景回归测试,覆盖统一时间轴和多对象组合。