# 网页粒子系统 · 阶段十二开发日志 > 阶段定位:**子发射器、Spine 预览层级、贴图轴点、独立 AB 循环与多版本导出完善** > 完成日期:2026-10-22 > 工程目录:`/Users/tianmokeji/Desktop/SpineParticle` > 技术栈:Vue 3 + TypeScript + Pinia + PixiJS 7 + Spine Runtime + Vite --- ## 一、阶段结论 阶段十二在阶段十一的粒子编辑与 Spine 导出体系上,补齐了复杂效果编排和实际项目使用中需要的能力。 本阶段重点不再是单一粒子的基础参数,而是粒子系统之间的关系、粒子与 Spine 场景的关系,以及烘焙导出后的可编辑性。完成后的编辑器可以制作父粒子触发的多层子粒子效果,在 Spine 插槽上下预览粒子,对贴图轴点进行可视化调整,并使用独立的 A/B 区间检查循环衔接。 阶段十二主要完成: 1. 新增出生、死亡、碰撞三类子发射器事件; 2. 新增子发射器目标、发射概率、属性继承和碰撞触发上限; 3. 建立父子发射器关系、循环依赖保护和事件链深度限制; 4. 子发射器进入场景树嵌套显示,不再独立自动发射; 5. 时间轴增加子发射器活动区间、启动标记和完整时长计算; 6. AB 循环改为独立开关和上浮输入窗,不再依赖持续发射循环; 7. 新增粒子在 Spine 插槽图片之上、之下的预览层级; 8. 渲染层级支持运行时 drawOrder 变化,并保持世界坐标稳定; 9. 图片资源卡新增可视化贴图轴点编辑器; 10. 贴图轴点支持画布拖动、滚轮缩放、坐标输入和超出图片范围; 11. 贴图轴点写入 Spine 附件偏移,参与最终烘焙导出; 12. Spine JSON 导出扩展为 3.8、4.0、4.1、4.2、4.3; 13. 修复子发射器在导出前暂停补齐时没有进入逐帧事件录制的问题; 14. 修复子发射器因自身生命周期较短而被错误截断帧的问题; 15. 增加子发射器、碰撞次数、AB 循环和层级绑定的配置迁移。 阶段十二完成后,粒子编辑器已经具备从设计、组合、预览、循环检查到 Spine 烘焙导出的完整工作流。 --- ## 二、子发射器系统 ### 2.1 事件类型 每条规则可选择一种父粒子事件: | 事件 | 触发时机 | |---|---| | 出生 | 父粒子刚生成时触发 | | 死亡 | 父粒子生命周期结束时触发 | | 碰撞 | 父粒子接触启用的碰撞对象时触发 | 事件规则包含: - 目标粒子系统; - 发射概率; - 碰撞次数限制; - 属性继承; - 颜色继承方式。 ### 2.2 目标系统 被任意有效事件规则引用的粒子系统会成为子发射器: - 不再独立自动发射; - 只由父粒子事件生成; - 在场景对象列表中嵌套到父系统下方; - 在时间轴中使用灰色子发射器轨道; - 移除引用或关闭“开启子发射器”后恢复普通系统。 子发射器选择列表会排除自身和全部上游父系统,避免形成循环引用。 事件链最多继续两级,防止跨系统事件无限递归。 ### 2.3 发射数量与延迟 子发射器仍使用自身的发射模式: - 爆发模式:每次事件生成“单次数量”颗粒子; - 持续模式:每次事件生成一颗事件粒子; - 子发射器 `delay`:父事件之后再等待指定秒数; - 延迟后的粒子仍会正常参与碰撞、修改器和生命周期更新。 ### 2.4 碰撞次数限制 碰撞事件可设置“碰撞次数限制”: - 默认值:1; - 整数范围:1~4; - 按每颗父粒子独立累计; - 粒子出生时碰撞次数归零; - 输入超出范围时立即钳制; - 只在事件类型为“碰撞”时显示。 该参数用于抑制粒子反弹、悬停或反复进出碰撞体导致的同一颗父粒子重复生成子粒子。 ### 2.5 属性继承 子发射器支持多选继承: | 属性 | 当前语义 | |---|---| | 颜色 | 按通道相加,或使用父粒子颜色覆盖 | | 大小 | 子粒子自身缩放 × 父粒子当前渲染缩放 | | 旋转 | 作为子发射系统整体发射方向和初始朝向偏移 | | 生命周期 | 覆盖子粒子生命周期,使用父粒子的完整 `maxLife` | 生命周期继承使用父粒子的完整生命周期,不使用剩余寿命,也不与子粒子自身寿命相加。 ### 2.6 烘焙要求 子发射器不能脱离父事件单独预热。阶段十二修复了两处烘焙问题: 1. 暂停时为根系统补帧后,旧逻辑会过早将整段动画标记为已烘焙,导致导出跳过事件录制; 2. 导出器按系统自身生命周期截断帧,导致较晚出现的子发射器帧被裁掉。 现在只有所有系统都具备完整帧缓存才可标记烘焙完成;子发射器导出时保留完整录制时间轴。 --- ## 三、时间轴与 AB 循环 ### 3.1 子发射器时间轴 子发射器在时间轴上显示为灰色条: - 起点为首次父事件时间加子发射器延迟; - 末端包含最后一次触发后的粒子生命周期; - 子发射器圆点标记系统启动时刻,不随子发射器 delay 拖动; - 拖动灰色条会增加延迟,但不能移动到父事件发生之前; - 总帧数会递归包含子发射器链; - 子发射器延长总长后,预览视口会自动扩展; - 关闭子发射器后,目标系统的独立时长重新计入总帧数。 ### 3.2 持续循环 时间轴的持续循环按钮只控制播放是否回到起点,与 AB 区间开关相互独立。 ### 3.3 AB 循环 AB 循环现在是一个独立开关: - 关闭时不显示 A/B 输入框,播放完整时间轴; - 开启时在时间轴上方浮出输入窗; - A、B 由用户直接输入; - 关闭后保留原值,下次开启可以继续使用; - “持续循环”开启时,AB 区间重复播放; - “持续循环”关闭时,播放到 B 后停止; - AB 状态和数值会进入配置文件。 ### 3.4 循环衔接原则 循环段仍遵守既有约束: - A/B 必须是精确的衔接状态; - 不通过复制首帧数值到尾帧制造表面闭环; - 粒子位置跳变只允许发生在粒子不可见时; - 循环开始、循环衔接和结束段需要在衔接帧强制 K 帧; - 强制 K 帧用于保留当前状态,方便后续在 Spine 中拆分动画; - 导出数据保留闭合边界,预览可以跳过数学边界帧避免停顿。 --- ## 四、Spine 插槽渲染层级 ### 4.1 预览层级 粒子系统可选择: - 最上层; - Spine 插槽; - 指定插槽图片之上; - 指定插槽图片之下。 插槽列表按 drawOrder 排列,并显示附件信息和搜索框。 ### 4.2 动画 drawOrder Spine 动画改变插槽绘制顺序时,编辑器会按当前动画帧的 drawOrder 重新解析实际挂载位置。 粒子容器使用坐标补偿抵消插槽骨骼变换,因此改变显示层级不会改变粒子在场景中的世界位置。 同一插槽可以同时承载多个粒子系统。 ### 4.3 导出边界 渲染层级只影响编辑器预览,不写入 Spine 导出数据。 若需要粒子位于 Spine 插槽之间,应在 Spine 编辑器中建立对应层级,再放入烘焙后的粒子骨骼和插槽。 --- ## 五、贴图轴点编辑器 图片资源卡增加“贴图轴点”开关。 开启后可以: - 在图片预览中直接拖动轴点; - 右键拖动画布; - 使用滚轮缩放画布; - 输入精确 X/Y 百分比; - 将轴点设置在图片范围之外; - 放大到全屏工作; - 恢复默认居中; - 重置当前图片轴点。 轴点十字线保持固定屏幕尺寸,并延伸为横竖无限长参考线。 轴点和开关状态跟随每张图片资源独立保存,不会因修改其他粒子参数而重置。 导出时轴点会转换为 Spine Region 附件的偏移,属于实际烘焙数据。 --- ## 六、Spine 资源与多版本导出 ### 6.1 Spine 场景对象 支持加载 Spine 的 skeleton、atlas 和图片资源,并提供: - 动画列表与预览; - 骨骼层级树; - 骨骼搜索和选择; - 插槽列表与附件名称; - 动画 drawOrder; - 粒子发射器跟随骨骼; - 粒子预览插槽层级。 支持 Spine 3.8、4.0、4.1、4.2、4.3 资源预览。 ### 6.2 JSON 导出 导出设置支持: - Spine 3.8 / 4.0 / 4.1 / 4.2 / 4.3; - 图片路径; - 线性或平滑贝塞尔; - 导出 FPS; - 不写 fps; - 整数帧对齐; - 骨骼对象池; - 排除无内容动画。 Spine 3.8 不支持 4.x 的逐通道数组贝塞尔,导出时会转换为经过容差精简的分段线性关键帧。 ### 6.3 图片与工程包 导出入口包含: - Spine JSON; - images 图片 ZIP; - 通过本地连接器生成 `.spine` 工程包。 连接器仅监听本机地址,使用已安装的 Spine 进行转换,并自动匹配项目 JSON 版本。 --- ## 七、当前完整功能模块 ### 7.1 配置管理 - 保存配置; - 加载配置; - 预设; - 快捷键保存; - 系统设置与工程配置分离; - 配置版本校验和旧字段迁移。 - 配置保存到浏览器 IndexedDB,并显示本地配置列表; - 列表支持加载、删除和单文件下载; - 支持把全部浏览器配置打包为 ZIP 下载; - 配置管理标题栏提供下载当前场景的快捷按钮; - 加载本地配置前提示会覆盖当前场景。 ### 7.2 场景对象 - 粒子系统; - 碰撞体; - 贝塞尔路径; - Spine 资源; - 对象复制; - 显隐控制; - 对象树和父子发射器嵌套。 ### 7.3 发射模式 - 持续发射; - 单次爆发; - 延迟; - 常规持续; - 循环持续; - 循环开始、纯循环、结束三段。 ### 7.4 发射器形状 - 点; - 圆形环带; - 矩形环带; - 锥形; - 路径出生线; - 固定、随机、径向、路径法线、路径切线角度。 ### 7.5 粒子属性 - 生命周期; - 速度; - 缩放; - 初始旋转; - 生命周期内速度、缩放、旋转变化; - 固定、随机、曲线取值; - 多轴分离缩放。 ### 7.6 外观与资源 - 单图与序列帧; - 多图片权重随机; - 图片缩放和贴图轴点; - 固定色、随机色、生命周期渐变; - 每张图片独立透明度; - 正常、相加、相乘、滤色混合; - 粒子系统透明度曲线。 ### 7.7 修改器 - 移动噪声; - 重力; - 风力; - 全局力场; - 漩涡; - 吸附; - 阻尼; - 碰撞与碰撞响应; - 拖尾; - 路径跟随; - Spine 骨骼跟随; - 子发射器。 ### 7.8 时间轴 - 播放、暂停和逐帧; - 持续循环; - 独立 AB 循环; - 自动总时长; - 发射段和粒子存在段; - Spine 动画条; - 子发射器灰色条; - 多动画归属; - 循环段快捷范围已由独立 AB 输入替代。 ### 7.9 导出 - Spine JSON; - images ZIP; - `.spine` 工程包; - 子发射器事件结果烘焙; - 碰撞结果烘焙; - 路径和 Spine 跟随结果烘焙; - 拖尾加权 Mesh; - 关键帧精简; - 结构校验。 ### 7.10 多语言 - 使用 `vue-i18n` 管理中英文及后续语言; - 当前支持简体中文、繁体中文、英语、日语、韩语、法语、德语、葡萄牙语和西班牙语; - 语言下拉框位于画布顶部工具栏、背景图与使用说明之间; - 首次访问按浏览器语言自动选择,无法匹配时回退英文; - 自动识别结果和手动选择均写入浏览器缓存; - 配置字段、Spine 枚举和导出数据保持语言无关,只切换显示文本; - 页面标题、参数面板、时间轴、使用说明、配置状态和主要错误提示均随语言切换。 --- ## 八、数据结构与兼容 阶段十二新增或完善的主要配置字段: ```text ParticleEventRule.collisionLimit TimelineState.abLoop EditorConfigFile.timeline.playbackEndAuto EditorConfigFile.timeline.abLoop EmitterConfig.renderLayerMode EmitterConfig.renderLayerSpineId EmitterConfig.renderLayerSlotName EmitterConfig.renderLayerSlotPosition EmitterConfig.renderLayerFollowAttachment ParticleImageResource.anchorX ParticleImageResource.anchorY ``` 旧配置处理: - 缺少碰撞限制时补为 1; - 缺少 AB 开关时默认关闭; - 旧 B 帧若原本是完整末帧,加载时迁移到新的完整末帧; - 无渲染层级字段时恢复“最上层”; - 无轴点字段时恢复 0.5 / 0.5; - 关闭“开启子发射器”后,保留规则但不再把目标识别为子发射器。 --- ## 九、主要代码落点 | 文件 | 阶段十二职责 | |---|---| | `src/core/particleEmitter.ts` | 事件触发、碰撞计数、子粒子生成、属性继承 | | `src/core/subEmitterIds.ts` | 子发射器引用、上游关系和循环依赖保护 | | `src/core/subEmitterTiming.ts` | 子发射器触发区间和总时长 | | `src/views/stage/emitterSync.ts` | 跨系统事件分发、概率、碰撞上限、自动发射切换 | | `src/views/stage/renderLayer.ts` | 插槽渲染目标解析 | | `src/views/Stage.vue` | 事件逐帧录制、帧缓存、子发射器烘焙 | | `src/views/Timeline.vue` | 子发射器条、AB 循环浮窗、启动标记、视图缩放 | | `src/views/ImageResourceCard.vue` | 图片轴点开关和资源卡入口 | | `src/views/PivotEditor.vue` | 轴点画布、缩放、拖动和全屏编辑 | | `src/views/particle-panel/ParticleModifiersSection.vue` | 子发射器卡片、继承和碰撞限制 UI | | `src/views/particle-panel/ParticleAppearanceSection.vue` | 渲染层级和资源面板 | | `src/export/spineJsonExporter.ts` | 多版本 JSON、子发射器完整帧导出、轴点偏移 | | `src/editor/editorConfig.ts` | 配置保存、加载和旧配置迁移 | | `src/store/particleStore.ts` | 时间轴、独立 AB、总帧数和播放范围 | --- ## 十、验证结果 阶段十二执行并通过: ```text npm run test:particle-events npm run test:sub-emitter-timeline npm run test:timeline npm run test:loop-seam npm run test:render-layer npm run test:spine-json npm run test:vortex npx vue-tsc -b npm run build ``` 浏览器实测包括: - 出生、死亡、碰撞事件均能生成目标子粒子; - 碰撞次数限制能减少重复触发; - 关闭子发射器后,对象树、自动发射和时间轴恢复正常; - Spine 插槽层级支持动画 drawOrder; - 轴点画布支持拖动、滚轮缩放和超出边界坐标; - AB 关闭播放完整时间轴,开启后按用户输入区间播放; - 子发射器在导出前能生成完整帧缓存; - 导出 JSON 包含一级和二级子发射器轨道; - 当前测试场景导出骨骼数由错误的 8 根恢复为 140 根; - `Burst_Collid_0`~`Burst_Collid_89` 已进入 Spine JSON; - `dist/` 生产构建成功。 --- ## 十一、当前边界 - 子发射器事件链最多两级; - 碰撞次数限制为 1~4; - 渲染层级仅影响编辑器预览,不参与 Spine 动画数据导出; - 贴图轴点会烘焙进 Spine 附件偏移; - `.spine` 工程包需要本机安装并启动连接器; - Spine 3.8 的贝塞尔表达受旧格式限制,会转换为精简线性关键帧; - 非常长的子发射器延迟会增加录制与导出时长; - 预览循环和导出闭环继续遵守“精确衔接、不可见时才允许跳变”的约束。 --- ## 十二、阶段十二最终状态 阶段十二完成后,SpineParticle 已具备: - 多粒子系统父子事件编排; - 出生、死亡、碰撞三种事件链; - 子粒子颜色、大小、旋转和生命周期继承; - 可控的重复碰撞触发; - Spine 插槽上下预览层级; - 可视化贴图轴点; - 独立 AB 循环检查; - 子发射器完整烘焙; - Spine 3.8~4.3 JSON 导出; - JSON、图片包和 `.spine` 工程包输出; - 配置文件、预设、复制和撤回完整联动。 至此,阶段十二“复杂粒子编排与 Spine 生产链路完善”完成落盘。