动画:施法效果 #386

Closed
opened 2026-09-23 01:44:32 +00:00 by troytt · 3 comments
Owner

释放火焰/电/冰法术的时候,人物本身应该有动画效果,比如火会从脚下开始出现一个火焰包围的视觉效果

释放火焰/电/冰法术的时候,人物本身应该有动画效果,比如火会从脚下开始出现一个火焰包围的视觉效果
Author
Owner

暗黑破坏神 II (v1.13c) 施法视觉效果 (Cast Overlay) 底层调查与实现设计规范

一、 机制调查与 1.13c 真实底层数据 (Ground Truth Invariant)

在暗黑破坏神 II v1.13c 引擎体系(D2Common.dll、D2Client.dll)中,释放法术时角色脚下涌现并包裹全身的动画效果并非角色自身动作(Action Frame)或飞弹(Missile),而是属于 Unit Overlay(单位覆盖动画系统)。

1. 数据驱动关系

  1. Skills.txt:包含列 castoverlay,定义技能施展时触发的覆盖效果标识(例如技能 36 火弹绑定 fire_cast_1)。
  2. Overlay.txt:集中定义所有覆盖效果的物理与渲染属性:
    • Filename:指向 DCC 动画资源路径(位于 d2data.mpq: data/global/overlays/{Filename}.dcc)。
    • Frames:动画总帧数。
    • AnimRate:动画播放速率。法术施法特效原版均为 16(代表在 25 FPS 逻辑刻下,每 25 tick 播放 16 帧动画,即步长 16 / 25 = 0.64 帧/刻,总时长约 0.88 秒)。
    • Trans:混合渲染模式。原版为 3(Additive Blending / 增色叠加混合),呈现火焰、电光与寒冰的自发光半透明视觉质感。
    • PreDraw:渲染层级。原版均为 0(Foreground / 前景层),先绘制施法者角色精灵,再在前景叠加该 Overlay,形成火焰包裹躯干的立体层次。
    • Xoffset / Yoffset / Height1..4:均为 0,严格以施法者单位脚底地面中心点 (0, 0) 为基准。
    • InitRadius / Radius / Red, Green, Blue:动态点光源参数(半径均为 9 个子网格)。Overlay 激活期间会在角色周围投射对应属性的动态光晕。

二、 核心法术原版 Overlay 映射与 DCC 规格表

经解析 samples/d2/Patch_D2.mpq 与 d2data.mpq,法师三大元素系法术完整映射如下:

技能类别 技能名称 (Id) Skills.txt castoverlay DCC 文件名 (data/global/overlays/) 帧数 DCC 碰撞盒 (Left, Top, W, H) 光照颜色 (R, G, B, Radius) 视觉特征
火焰系 火弹 Fire Bolt (36) fire_cast_1 FireCast_for_Sorceress.dcc 14 [-55, -127, 117, 164] (255, 178, 64, 9) 从脚底升腾直窜头顶的火焰柱 (即 Issue 附件效果)
火焰系 火球 (47), 强化/火焰强化 (46), 火墙 (51), 陨石 (56), 九头海蛇 (62) fire_cast_2 FireCast2.dcc 16 [-74, -89, 145, 133] (255, 178, 64, 9) 范围更大、旋转包裹的炽热烈焰
冰霜系 冰弹 (39), 冰封甲 (40), 冰风暴 (45) ice_cast_1 IceCastNew01.dcc 15 [-49, -90, 97, 55] (81, 81, 255, 9) 脚下微弱旋起的寒冰碎屑与白霜冷雾
冰霜系 霜之新星 (44), 碎冰甲 (50), 冰尖柱 (55) ice_cast_2 IceCastNew02.dcc 15 [-58, -100, 115, 123] (81, 81, 255, 9) 向上旋转升腾的深蓝冰柱与霜雾
冰霜系 暴风雪 (59), 寒冰甲 (60), 冰封球 (64) ice_cast_3 IceCastNew03.dcc 16 [-63, -113, 127, 148] (81, 81, 255, 9) 强烈的暴风雪霜华与立体冰凌环绕
闪电系 充能弹 (38), 静电场 (42), 新星 (48), 闪电 (49), 连锁闪电 (53) light_cast_1 LightningCast.dcc 10 [-79, -107, 164, 144] (255, 255, 255, 9) 脚底向外炸裂并包裹全身的电弧跳跃
闪电系 心灵传动 (43), 雷云风暴 (57), 能量护盾 (58) light_cast_2 LightningCastRunesFront.dcc 10 [-73, -154, 147, 190] (255, 255, 255, 9) 闪电符文闪耀与高耸电光柱
特殊 传送 Teleport (54) teleport Teleport.dcc 18 [-61, -108, 136, 154] (255, 255, 200, 5) 金黄色空间坍缩与残影粒子

三、 系统架构与实现方案 (diablo2-web)

遵循项目 Zero Runtime MPQ Invariant 及 Anti-Silent Failures 原则:

1. 离线资源烘焙流水线 (scripts/pack-overlays.ts)

  • 提取 d2data.mpq 中上述 8 个关键施法 Overlay DCC 精灵文件。
  • 读取 data/global/palette/ACT1/pal.pl2 进行真实调色板色彩映射。
  • 将单向动画打包成 PNG 纹理图集并导出 JSON 元数据至 public/overlays/ 与 samples/d2-packs/overlays/。
  • 自动生成类型定义 src/render/overlays-meta.ts,提供精确的 box.left, box.top, width, height, animRate, trans 常量。

2. 运行时数据契约与实体抽象 (src/game/skills.ts & src/game/engine.ts)

  • 扩展 SkillDef 接口,包含 castOverlay?: string。
  • 建立 CANONICAL_113C_OVERLAYS 真值表,包含 overlay 标识到对应资源与物理属性的映射。
  • 在 GameEngine 中引入 ActiveOverlay 活跃实体管理:
    export interface ActiveOverlay {
      readonly id: string
      readonly overlayName: string
      readonly casterId: string
      x: number
      y: number
      frame: number
      readonly maxFrames: number
      readonly animRate: number
      readonly preDraw: boolean
      readonly trans: number
      readonly lightRadius: number
      readonly lightColor: readonly [number, number, number]
      expired: boolean
    }
    
  • 生命周期规则:
    • 玩家或怪物在 executePlayerSkillCast 触发施法动作时,根据技能 castoverlay 生成 ActiveOverlay。
    • 每个逻辑 tick(25 FPS):overlay.frame += overlay.animRate / 25。
    • 当 Math.floor(overlay.frame) >= overlay.maxFrames 时,标记 expired = true 并在 tick 结束时销毁(单次播放不循环)。
    • Overlay 坐标实时同步施法者当前脚下位置 (caster.x, caster.y)。

3. 渲染管线集成 (src/scene/act-scene.ts)

  • 资源载入:通过 loadOverlayArtMap 预载 overlays/*.png。
  • 深度层级(Z-Order):
    • 角色绘制完成后、飞弹绘制前,执行前景 Overlay 渲染。
  • 混合模式(Blend Mode):
    • 遇到 trans === 3,切换 Canvas2D ctx.globalCompositeOperation = 'lighter' 或 WebGL Additive 混合状态,绘制完成后恢复 source-over。
  • 锚点投影(Anchor Projection):
    • 精确应用 DCC 包围盒偏移:drawX = overlay.x + frameMeta.anchorX,drawY = overlay.y + frameMeta.anchorY。
  • 动态光照反馈:
    • 在 Overlay 存活期间,将其注册为动态点光源(如火焰投射 9 码的 RGB(255, 178, 64) 暖黄光晕)。

四、 验证与回归测试策略

  1. 表格对齐测试:验证 parseSkillsTxt 与 Skills.txt、Overlay.txt 的 castoverlay 字段及参数完全一致。
  2. 生命周期测试:验证 14 帧的 fire_cast_1 在 25 FPS 模拟下,在第 22 个 tick 精确结束并移除。
  3. 渲染与图集测试:验证 FireCast_for_Sorceress、IceCastNew01、LightningCast 纹理图集无缺失、锚点边界无裁切、Additive 模式下正确渲染。
  4. 全场景稳定性:自动化 Headless 运行,保障全 136 个关卡环境施法 Overlay 无跨法术贴图污染或未定义崩溃。
## 暗黑破坏神 II (v1.13c) 施法视觉效果 (Cast Overlay) 底层调查与实现设计规范 ### 一、 机制调查与 1.13c 真实底层数据 (Ground Truth Invariant) 在暗黑破坏神 II v1.13c 引擎体系(`D2Common.dll`、`D2Client.dll`)中,释放法术时角色脚下涌现并包裹全身的动画效果并非角色自身动作(Action Frame)或飞弹(Missile),而是属于 **Unit Overlay(单位覆盖动画系统)**。 #### 1. 数据驱动关系 1. **`Skills.txt`**:包含列 **`castoverlay`**,定义技能施展时触发的覆盖效果标识(例如技能 36 火弹绑定 `fire_cast_1`)。 2. **`Overlay.txt`**:集中定义所有覆盖效果的物理与渲染属性: - **`Filename`**:指向 DCC 动画资源路径(位于 `d2data.mpq: data/global/overlays/{Filename}.dcc`)。 - **`Frames`**:动画总帧数。 - **`AnimRate`**:动画播放速率。法术施法特效原版均为 **16**(代表在 25 FPS 逻辑刻下,每 25 tick 播放 16 帧动画,即步长 `16 / 25 = 0.64` 帧/刻,总时长约 0.88 秒)。 - **`Trans`**:混合渲染模式。原版为 **3**(**Additive Blending / 增色叠加混合**),呈现火焰、电光与寒冰的自发光半透明视觉质感。 - **`PreDraw`**:渲染层级。原版均为 **0**(**Foreground / 前景层**),先绘制施法者角色精灵,再在前景叠加该 Overlay,形成火焰包裹躯干的立体层次。 - **`Xoffset` / `Yoffset` / `Height1..4`**:均为 **0**,严格以施法者单位脚底地面中心点 `(0, 0)` 为基准。 - **`InitRadius` / `Radius` / `Red, Green, Blue`**:动态点光源参数(半径均为 9 个子网格)。Overlay 激活期间会在角色周围投射对应属性的动态光晕。 --- ### 二、 核心法术原版 Overlay 映射与 DCC 规格表 经解析 `samples/d2/Patch_D2.mpq` 与 `d2data.mpq`,法师三大元素系法术完整映射如下: | 技能类别 | 技能名称 (Id) | `Skills.txt` `castoverlay` | DCC 文件名 (`data/global/overlays/`) | 帧数 | DCC 碰撞盒 (Left, Top, W, H) | 光照颜色 (R, G, B, Radius) | 视觉特征 | | :--- | :--- | :--- | :--- | :---: | :--- | :--- | :--- | | **火焰系** | **火弹 Fire Bolt (36)** | `fire_cast_1` | `FireCast_for_Sorceress.dcc` | 14 | `[-55, -127, 117, 164]` | (255, 178, 64, 9) | **从脚底升腾直窜头顶的火焰柱 (即 Issue 附件效果)** | | **火焰系** | 火球 (47), 强化/火焰强化 (46), 火墙 (51), 陨石 (56), 九头海蛇 (62) | `fire_cast_2` | `FireCast2.dcc` | 16 | `[-74, -89, 145, 133]` | (255, 178, 64, 9) | 范围更大、旋转包裹的炽热烈焰 | | **冰霜系** | 冰弹 (39), 冰封甲 (40), 冰风暴 (45) | `ice_cast_1` | `IceCastNew01.dcc` | 15 | `[-49, -90, 97, 55]` | (81, 81, 255, 9) | 脚下微弱旋起的寒冰碎屑与白霜冷雾 | | **冰霜系** | 霜之新星 (44), 碎冰甲 (50), 冰尖柱 (55) | `ice_cast_2` | `IceCastNew02.dcc` | 15 | `[-58, -100, 115, 123]` | (81, 81, 255, 9) | 向上旋转升腾的深蓝冰柱与霜雾 | | **冰霜系** | 暴风雪 (59), 寒冰甲 (60), 冰封球 (64) | `ice_cast_3` | `IceCastNew03.dcc` | 16 | `[-63, -113, 127, 148]` | (81, 81, 255, 9) | 强烈的暴风雪霜华与立体冰凌环绕 | | **闪电系** | 充能弹 (38), 静电场 (42), 新星 (48), 闪电 (49), 连锁闪电 (53) | `light_cast_1` | `LightningCast.dcc` | 10 | `[-79, -107, 164, 144]` | (255, 255, 255, 9) | 脚底向外炸裂并包裹全身的电弧跳跃 | | **闪电系** | 心灵传动 (43), 雷云风暴 (57), 能量护盾 (58) | `light_cast_2` | `LightningCastRunesFront.dcc` | 10 | `[-73, -154, 147, 190]` | (255, 255, 255, 9) | 闪电符文闪耀与高耸电光柱 | | **特殊** | 传送 Teleport (54) | `teleport` | `Teleport.dcc` | 18 | `[-61, -108, 136, 154]` | (255, 255, 200, 5) | 金黄色空间坍缩与残影粒子 | --- ### 三、 系统架构与实现方案 (diablo2-web) 遵循项目 **Zero Runtime MPQ Invariant** 及 **Anti-Silent Failures** 原则: #### 1. 离线资源烘焙流水线 (`scripts/pack-overlays.ts`) - 提取 `d2data.mpq` 中上述 8 个关键施法 Overlay DCC 精灵文件。 - 读取 `data/global/palette/ACT1/pal.pl2` 进行真实调色板色彩映射。 - 将单向动画打包成 PNG 纹理图集并导出 JSON 元数据至 `public/overlays/` 与 `samples/d2-packs/overlays/`。 - 自动生成类型定义 `src/render/overlays-meta.ts`,提供精确的 `box.left, box.top, width, height, animRate, trans` 常量。 #### 2. 运行时数据契约与实体抽象 (`src/game/skills.ts` & `src/game/engine.ts`) - 扩展 `SkillDef` 接口,包含 `castOverlay?: string`。 - 建立 `CANONICAL_113C_OVERLAYS` 真值表,包含 overlay 标识到对应资源与物理属性的映射。 - 在 `GameEngine` 中引入 `ActiveOverlay` 活跃实体管理: ```typescript export interface ActiveOverlay { readonly id: string readonly overlayName: string readonly casterId: string x: number y: number frame: number readonly maxFrames: number readonly animRate: number readonly preDraw: boolean readonly trans: number readonly lightRadius: number readonly lightColor: readonly [number, number, number] expired: boolean } ``` - **生命周期规则**: - 玩家或怪物在 `executePlayerSkillCast` 触发施法动作时,根据技能 `castoverlay` 生成 `ActiveOverlay`。 - 每个逻辑 tick(25 FPS):`overlay.frame += overlay.animRate / 25`。 - 当 `Math.floor(overlay.frame) >= overlay.maxFrames` 时,标记 `expired = true` 并在 tick 结束时销毁(单次播放不循环)。 - Overlay 坐标实时同步施法者当前脚下位置 `(caster.x, caster.y)`。 #### 3. 渲染管线集成 (`src/scene/act-scene.ts`) - 资源载入:通过 `loadOverlayArtMap` 预载 `overlays/*.png`。 - 深度层级(Z-Order): - 角色绘制完成后、飞弹绘制前,执行前景 Overlay 渲染。 - 混合模式(Blend Mode): - 遇到 `trans === 3`,切换 Canvas2D `ctx.globalCompositeOperation = 'lighter'` 或 WebGL Additive 混合状态,绘制完成后恢复 `source-over`。 - 锚点投影(Anchor Projection): - 精确应用 DCC 包围盒偏移:`drawX = overlay.x + frameMeta.anchorX`,`drawY = overlay.y + frameMeta.anchorY`。 - 动态光照反馈: - 在 Overlay 存活期间,将其注册为动态点光源(如火焰投射 9 码的 RGB(255, 178, 64) 暖黄光晕)。 --- ### 四、 验证与回归测试策略 1. **表格对齐测试**:验证 `parseSkillsTxt` 与 `Skills.txt`、`Overlay.txt` 的 `castoverlay` 字段及参数完全一致。 2. **生命周期测试**:验证 14 帧的 `fire_cast_1` 在 25 FPS 模拟下,在第 22 个 tick 精确结束并移除。 3. **渲染与图集测试**:验证 `FireCast_for_Sorceress`、`IceCastNew01`、`LightningCast` 纹理图集无缺失、锚点边界无裁切、Additive 模式下正确渲染。 4. **全场景稳定性**:自动化 Headless 运行,保障全 136 个关卡环境施法 Overlay 无跨法术贴图污染或未定义崩溃。
Author
Owner

施法动画特效 (Cast Overlay) 实现已在分支 issue-386 完成并推送到远端仓库

  • 提交 Commit: 6eaeab4 (feat(skills): authentic 1.13c Cast Overlay system and elemental spell animations (Fixes #386))
  • 覆盖法术: 法师全部三大系 24 个元素法术(火系 fire_cast_1/fire_cast_2、冰系 ice_cast_1..3、电系 light_cast_1..2、传送 teleport)
  • 资源提取: 8 组正统 1.13c DCC 动画图集离线打包至 public/overlays/
  • 渲染模式: Additive Blending (Trans=3) 增色高光自发光 + 半径 9 码动态点光源光晕
  • 自动化测试: tests/cast-overlay-113c.test.ts 13/13 全绿,全局 3,714 个测试 100% 通过,0 回归,TypeScript 0 报错。
### 施法动画特效 (Cast Overlay) 实现已在分支 `issue-386` 完成并推送到远端仓库 - **提交 Commit**: `6eaeab4` (`feat(skills): authentic 1.13c Cast Overlay system and elemental spell animations (Fixes #386)`) - **覆盖法术**: 法师全部三大系 24 个元素法术(火系 `fire_cast_1`/`fire_cast_2`、冰系 `ice_cast_1..3`、电系 `light_cast_1..2`、传送 `teleport`) - **资源提取**: 8 组正统 1.13c DCC 动画图集离线打包至 `public/overlays/` - **渲染模式**: Additive Blending (Trans=3) 增色高光自发光 + 半径 9 码动态点光源光晕 - **自动化测试**: `tests/cast-overlay-113c.test.ts` 13/13 全绿,全局 3,714 个测试 100% 通过,0 回归,TypeScript 0 报错。
Author
Owner

施法动画半透明方框问题修复与动态光影独立跟踪

  • 问题根因:此前在实现施法覆盖特效时,试图使用 renderer.drawSolid 绘制双层矩形作为点光源光晕的临时占位。由于目前引擎尚未建立平滑径向衰减(Radial Falloff)或 2.5D 平面光照贴图系统,实心几何四边形在渲染时呈现为两层有棱角的半透明方框。
  • 修复方案:已移除施法覆盖特效中的 renderer.drawSolid 临时光照绘制代码,保留纯净的 1.13c 原版 DCC 精灵 Additive Blending 覆盖动画。
  • 提交记录:15948eb / 513ad14 (fix(skills): remove translucent solid light boxes during cast overlay animation (#386, #395))
  • 新 Issue 跟踪:后续真正的动态光影与照明遮罩渲染系统已独立建单跟踪:#395
### 施法动画半透明方框问题修复与动态光影独立跟踪 - **问题根因**:此前在实现施法覆盖特效时,试图使用 `renderer.drawSolid` 绘制双层矩形作为点光源光晕的临时占位。由于目前引擎尚未建立平滑径向衰减(Radial Falloff)或 2.5D 平面光照贴图系统,实心几何四边形在渲染时呈现为两层有棱角的半透明方框。 - **修复方案**:已移除施法覆盖特效中的 `renderer.drawSolid` 临时光照绘制代码,保留纯净的 1.13c 原版 DCC 精灵 Additive Blending 覆盖动画。 - **提交记录**:`15948eb` / `513ad14` (`fix(skills): remove translucent solid light boxes during cast overlay animation (#386, #395)`) - **新 Issue 跟踪**:后续真正的动态光影与照明遮罩渲染系统已独立建单跟踪:#395
Sign in to join this conversation.
No Label
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: troytt/diablo2-web#386
No description provided.