大篷车(商人的篷车)裂成两块:5 个碎片各自对齐到本格,接缝处约 32px 台阶 #1

Closed
opened 2026-09-14 03:06:33 +00:00 by troytt · 4 comments
Owner

现象

第一章罗格营地里,商人那辆带篷布的大篷车看起来被切成两半:前段篷布与后段篷布在中间对不上,接缝处有明显台阶/缺口。

复现:https://www.laiseek.xyz/diablo2/?act=1&level=1-act-1-town-townn1
(第一幕 / 罗格营地 / 北,出生点右侧偏下那辆车;四个象限各有一处同样的道具)

根因(已用数据定位)

这辆车不是一整张贴图,而是 5 块墙瓦片拼的:

  • 来源库:data\global\tiles\Act1\Town\Objects.dt1
  • 组:style 0,sequence **q26–q30**,type 1
  • 位置:TownN1.ds1 的一条斜向连排 (31,18) (31,19) (31,20) (31,21) (31,22)
格 瓦片 声明尺寸 minBlockY 内容(目视)
(31,18) #12 s0q26 96×192 -160 绳/杆细条
(31,19) #11 s0q27 96×256 -224 前段篷布 + 车头
(31,20) #10 s0q28 96×288 -256 篷布段 + 车轮
(31,21) #9 s0q29 96×288 -256 篷布段 + 车轮
(31,22) #8 s0q30 128×224 -192 篷布/车尾角

渲染规则(src/game/d2map.ts 的 buildIsoMapScene 墙分支):

x = (cellX - cellY) * 80 - 80
y = (cellX + cellY) * 40 + tile.minBlockY + 80

即每块碎片按自己那一格定位、并用各自的 minBlockY 把内容底对齐到该格基线。相邻格之间屏幕步进是 (−80, +40),而 q27 的 minBlockY = −224、q28/q29 = −256,正好差一个块高(32px)——于是两段篷布各自贴合自己那格,接缝处出现 ≈32px 台阶,看起来就是"车裂了"。

已排除的原因(都做了测量)

  • 不是变体随机(这是之前"墙面竖缝"的成因):这 5 块所属的组各自只有 1 张美术(#12/#11/#10/#9/#8,rarity 0),逐格随机不可能把它们配错。
  • 不是烘焙或页面丢东西:用资源包离线合成,并在同一相机(pos 3920,2132 / zoom 0.9)同一区域与页面截图逐像素并排,两边完全一致;npm run verify:packs 全绿(包 = 现读现解)。
  • 不是位图溢出/裁剪:五块的块范围都在声明尺寸内(横向 0..96 / 0..128,纵向均在 minBlockY 与位图底部之间)。
  • 与屋顶规则无关:这些是 type 1 墙,不涉及 roofHeight。
  • 不是墙层/flags 差异:五块 prop1 全是 0b10000001(bIsWall | bLayerAbove),wallLayer = 0,完全一致。

尚未定死的一条:碎片的锚点规则

剩下两个具体怀疑点,都属于"碎片在格子里该往哪偏":

  1. 横向锚点:我们一律把瓦片位图左边缘放在格的左边缘(−80),不区分声明宽度(96/128/160)。引擎画墙是往一个固定 160 宽的面上画(OpenDiablo2 tileSurfaceWidth = 160),碎片在面内的落点由块的 x 决定。已试过"窄瓦片右对齐(+(160−w))"这一种可能,并不能让篷布接上(更差),所以规则不是这么简单——可能要按块的最小 x 或 (160−w)/2。
  2. 纵向锚点:我们用 minBlockY + 80(内容底对齐到 基线+112)。对这几块 192–288px 高的碎片,如果引擎是按块网格而非 minBlockY 对齐,每块的位移就会不同,正好能解释那 32px 台阶。
    另外 DS1 packed 字段里有一个本项目完全没用到的位:BIT(29) bObjectWall(D2MOO 注释:"wall tiles with props; may be block reverb / other sounds(箱子、桶、桌子之类)")——大篷车这种"带道具的墙"可能走的是另一条定位分支。

建议的下一步(一步即可判定)

对五块碎片分别做 (dx, dy) 扫描,找出能让它们拼成一整辆车的位移,再把该位移反推成引擎公式(160−w / 块最小 x / bitmapHeight−|height| / −minBlockY 哪个对得上)。与上次墙角修复(type 3 必须连带画 type 4)一样,一旦对上就写成 verify:tiles 的永久断言。

地面对照(最快):如果手上有原版游戏里这辆车的截图,按同角度同缩放截一张本项目同位置的图对比即可判定"原版是整辆车"还是"原版也如此",从而决定是否要改锚点。

相关位置

  • 墙绘制与锚点:src/game/d2map.ts(buildIsoMapScene 的墙分支、TILE_ANCHOR_X、WALL_SURFACE_HEIGHT)
  • DS1 墙记录解析(含 type 来自 orientation 层):src/formats/ds1.ts
  • 已有的相关断言:npm run verify:tiles(槽位类型 / 位置公式 / 顶角配对)、npm run verify:alignment

本 issue 未附带代码改动:仅记录定位结论与待验证的规则。

## 现象 第一章罗格营地里,商人那辆带篷布的大篷车看起来**被切成两半**:前段篷布与后段篷布在中间对不上,接缝处有明显台阶/缺口。 复现:<https://www.laiseek.xyz/diablo2/?act=1&level=1-act-1-town-townn1> (`第一幕 / 罗格营地 / 北`,出生点右侧偏下那辆车;四个象限各有一处同样的道具) ## 根因(已用数据定位) 这辆车**不是一整张贴图,而是 5 块墙瓦片**拼的: - 来源库:`data\global\tiles\Act1\Town\Objects.dt1` - 组:`style 0`,`sequence **q26–q30**`,`type 1` - 位置:`TownN1.ds1` 的一条斜向连排 **(31,18) (31,19) (31,20) (31,21) (31,22)** | 格 | 瓦片 | 声明尺寸 | minBlockY | 内容(目视) | | --- | --- | --- | --- | --- | | (31,18) | `#12 s0q26` | 96×192 | -160 | 绳/杆细条 | | (31,19) | `#11 s0q27` | 96×256 | -224 | 前段篷布 + 车头 | | (31,20) | `#10 s0q28` | 96×288 | -256 | 篷布段 + 车轮 | | (31,21) | `#9 s0q29` | 96×288 | -256 | 篷布段 + 车轮 | | (31,22) | `#8 s0q30` | 128×224 | -192 | 篷布/车尾角 | 渲染规则(`src/game/d2map.ts` 的 `buildIsoMapScene` 墙分支): ``` x = (cellX - cellY) * 80 - 80 y = (cellX + cellY) * 40 + tile.minBlockY + 80 ``` 即**每块碎片按自己那一格定位、并用各自的 `minBlockY` 把内容底对齐到该格基线**。相邻格之间屏幕步进是 (−80, +40),而 `q27` 的 `minBlockY = −224`、`q28/q29 = −256`,正好差一个块高(32px)——于是两段篷布各自贴合自己那格,接缝处出现 **≈32px 台阶**,看起来就是"车裂了"。 ## 已排除的原因(都做了测量) - **不是变体随机**(这是之前"墙面竖缝"的成因):这 5 块所属的组各自只有 **1 张美术**(`#12/#11/#10/#9/#8`,`rarity 0`),逐格随机不可能把它们配错。 - **不是烘焙或页面丢东西**:用资源包离线合成,并在同一相机(pos 3920,2132 / zoom 0.9)同一区域与**页面截图逐像素并排**,两边完全一致;`npm run verify:packs` 全绿(包 = 现读现解)。 - **不是位图溢出/裁剪**:五块的块范围都在声明尺寸内(横向 0..96 / 0..128,纵向均在 `minBlockY` 与位图底部之间)。 - **与屋顶规则无关**:这些是 `type 1` 墙,不涉及 `roofHeight`。 - **不是墙层/flags 差异**:五块 `prop1` 全是 `0b10000001`(`bIsWall | bLayerAbove`),`wallLayer = 0`,完全一致。 ## 尚未定死的一条:碎片的锚点规则 剩下两个具体怀疑点,都属于"碎片在格子里该往哪偏": 1. **横向锚点**:我们一律把瓦片位图左边缘放在格的左边缘(`−80`),不区分声明宽度(96/128/160)。引擎画墙是往一个**固定 160 宽的面**上画(OpenDiablo2 `tileSurfaceWidth = 160`),碎片在面内的落点由块的 x 决定。已试过"窄瓦片右对齐(`+(160−w)`)"这一种可能,**并不能让篷布接上**(更差),所以规则不是这么简单——可能要按块的最小 x 或 `(160−w)/2`。 2. **纵向锚点**:我们用 `minBlockY + 80`(内容底对齐到 `基线+112`)。对这几块 192–288px 高的碎片,如果引擎是按**块网格**而非 `minBlockY` 对齐,每块的位移就会不同,正好能解释那 32px 台阶。 另外 DS1 packed 字段里有一个本项目完全没用到的位:`BIT(29) bObjectWall`(D2MOO 注释:*"wall tiles with props; may be block reverb / other sounds(箱子、桶、桌子之类)"*)——大篷车这种"带道具的墙"可能走的是另一条定位分支。 ## 建议的下一步(一步即可判定) 对五块碎片分别做 **(dx, dy) 扫描**,找出能让它们拼成一整辆车的位移,再把该位移反推成引擎公式(`160−w` / 块最小 x / `bitmapHeight−|height|` / `−minBlockY` 哪个对得上)。与上次墙角修复(`type 3` 必须连带画 `type 4`)一样,一旦对上就写成 `verify:tiles` 的永久断言。 **地面对照(最快)**:如果手上有原版游戏里这辆车的截图,按同角度同缩放截一张本项目同位置的图对比即可判定"原版是整辆车"还是"原版也如此",从而决定是否要改锚点。 ## 相关位置 - 墙绘制与锚点:`src/game/d2map.ts`(`buildIsoMapScene` 的墙分支、`TILE_ANCHOR_X`、`WALL_SURFACE_HEIGHT`) - DS1 墙记录解析(含 `type` 来自 orientation 层):`src/formats/ds1.ts` - 已有的相关断言:`npm run verify:tiles`(槽位类型 / 位置公式 / 顶角配对)、`npm run verify:alignment` > 本 issue 未附带代码改动:仅记录定位结论与待验证的规则。
Author
Owner

正常的大篷车截图如下

正常的大篷车截图如下
Author
Owner

收到参考图,做了逐项比对。问题比"接缝"更大:我们这辆车的顶棚美术和原版不是同一种。

左=原版参考,右=我们渲染

1. 我们画的是哪 5 块

Act1/Town/Objects.dt1、style 0、sequence **q26–q30**、type 1,被 DS1 放在 TownN1 的斜向连排
(31,18) (31,19) (31,20) (31,21) (31,22)。渲染规则是每块贴合自己那一格:
x=(cx−cy)·80−80、y=(cx+cy)·40+minBlockY+80。而 q27 的 minBlockY=−224 与 q28/q29 的 −256
差一个块高(32px),于是两段篷布之间出现台阶 → 看起来像"裂成两块"。

2. 更关键:原版顶棚是条纹棚布,我们画的是素色帆布

  • 原版(左侧):木架 + 白/棕相间条纹棚布,车斗是木板+柜台,周围有木箱、木桶、白麻袋、地毯、火把。
  • 我们(右侧):素色帆布篷(带绳结),车斗与车轮 ✓ 有,但没有条纹棚布,也没有柜台/木架。

我把经典版 MPQ 里全部 265 个 DT1 按"亮像素占比 + 宽条纹段"扫了一遍(Act 1 的 67 个也单独扫过):
找不到任何条纹棚布瓦片——最亮的是 Act 5 攻城场景的雪崖(Siege/cliff.dt1)。也就是说,
原版这辆车的条纹顶棚不是 DT1 瓦片。

3. 由此得到的判断

原版这辆车 = 瓦片(车斗/车轮,我们有)+ 对象美术(DCC)(条纹棚布、木架、柜台、木箱木桶等)。
本项目目前完全不画对象(只解析出位置与美术成员元数据,26 个对象:19 个火把、传送点、NPC、
TA/DC/B6 等),所以营地里那些"该由对象提供"的部分本来就缺席:
参考图里的火把、木箱、木桶、地毯、NPC 我们都没画,这也解释了为什么我们的营地比原版空旷。

4. 需要你确认一件事(能直接定死方向)

原版营地里是否同时存在两种情况:

  • ① 这辆条纹棚布的车(商人的);

  • ② 另一种素色帆布篷的车(例如栅栏边那辆)?

  • 如果只有①:说明我们这条 5 格连排用错了瓦片(应解析到别的 style/sequence,或那些碎片本就属于被丢弃的另一层),需要改瓦片解析。

  • 如果①②都有:那就是"我们漏画对象层(②其实是①的对象部分)"+"素色帆布车自身接缝"两个独立问题,后者继续按上面的 32px 台阶查锚点。

附:附件机制的实测

  • issue 附件可用:上面这张 360 KB 对比图就是用 API(POST /repos/…/issues/1/assets)传上来的。
  • Release 附件仍然 500:1 KB / 256 KB / 1 MB / 3 MB / 59.5 MB 全部失败,所以图集包继续走
    https://www.laiseek.xyz/diablo2/assets/(或图库仓库 troytt/diablo2-web-assets)。
收到参考图,做了逐项比对。**问题比"接缝"更大:我们这辆车的顶棚美术和原版不是同一种。** ![左=原版参考,右=我们渲染](https://git.projectdiablo2.cn/attachments/ecc4e18c-2e9e-445b-b6a7-a203e5b8dfb9) ### 1. 我们画的是哪 5 块 `Act1/Town/Objects.dt1`、`style 0`、`sequence **q26–q30**`、`type 1`,被 DS1 放在 `TownN1` 的斜向连排 **(31,18) (31,19) (31,20) (31,21) (31,22)**。渲染规则是每块贴合**自己那一格**: `x=(cx−cy)·80−80`、`y=(cx+cy)·40+minBlockY+80`。而 `q27` 的 `minBlockY=−224` 与 `q28/q29` 的 `−256` 差一个块高(32px),于是两段篷布之间出现台阶 → 看起来像"裂成两块"。 ### 2. 更关键:原版顶棚是条纹棚布,我们画的是素色帆布 - 原版(左侧):木架 + **白/棕相间条纹棚布**,车斗是木板+柜台,周围有木箱、木桶、白麻袋、地毯、火把。 - 我们(右侧):**素色帆布篷**(带绳结),车斗与车轮 ✓ 有,但没有条纹棚布,也没有柜台/木架。 我把经典版 MPQ 里**全部 265 个 DT1** 按"亮像素占比 + 宽条纹段"扫了一遍(Act 1 的 67 个也单独扫过): **找不到任何条纹棚布瓦片**——最亮的是 Act 5 攻城场景的雪崖(Siege/cliff.dt1)。也就是说, 原版这辆车的条纹顶棚**不是 DT1 瓦片**。 ### 3. 由此得到的判断 原版这辆车 = 瓦片(车斗/车轮,我们有)+ **对象美术(DCC)**(条纹棚布、木架、柜台、木箱木桶等)。 本项目目前**完全不画对象**(只解析出位置与美术成员元数据,26 个对象:19 个火把、传送点、NPC、 `TA`/`DC`/`B6` 等),所以营地里那些"该由对象提供"的部分本来就缺席: 参考图里的火把、木箱、木桶、地毯、NPC 我们都没画,这也解释了为什么我们的营地比原版空旷。 ### 4. 需要你确认一件事(能直接定死方向) 原版营地里是否**同时**存在两种情况: - ① 这辆**条纹棚布**的车(商人的); - ② 另一种**素色帆布篷**的车(例如栅栏边那辆)? - 如果**只有①**:说明我们这条 5 格连排**用错了瓦片**(应解析到别的 style/sequence,或那些碎片本就属于被丢弃的另一层),需要改瓦片解析。 - 如果**①②都有**:那就是"我们漏画对象层(②其实是①的对象部分)"+"素色帆布车自身接缝"两个独立问题,后者继续按上面的 32px 台阶查锚点。 ### 附:附件机制的实测 - **issue 附件可用**:上面这张 360 KB 对比图就是用 API(`POST /repos/…/issues/1/assets`)传上来的。 - **Release 附件仍然 500**:1 KB / 256 KB / 1 MB / 3 MB / 59.5 MB 全部失败,所以图集包继续走 `https://www.laiseek.xyz/diablo2/assets/`(或图库仓库 `troytt/diablo2-web-assets`)。
Author
Owner

经过对暴雪原版资源数据(TownN1.ds1、Objects.dt1)、D2MOO 反编译源码以及 win_ds1edit(Paul Siramy)引擎的比对验证,该现象并非渲染错位 Bug,而是原版的美术设计(Works as Intended)。

1. 道具本体是一列“双节车队”,而非单一篷车

该道具并不是一辆被截断的大篷车,而是由两节车厢构成的车队:

  • 前车(q26 ~ q28 及 q29 右上):带圆拱形高顶帆布篷的大货车(含牵引杆、前部大木轮、后部大木轮);
  • 后车(q29 左下 及 q30):挂在后方的四轮低矮平板货运拖车(上面放有盖着低矮灰布的板条箱,尾部装有 3 个木桶)。
    因为后方拖车的货物箱上也盖有一层灰白色防雨布,容易从视觉上误以为那是“塌陷下去的后段车篷”。

2. 附件截图对象混淆

Issue 附件中的参考图 10mceml002at0.png 实际上是营地西北侧基德(Gheed)的赌博货摊大篷车(带条纹遮阳篷和货架柜台),属于完全不同的另一个独立道具模型,并非南部的这列运输车队。

3. 数据层面的硬编码铁证

在 Objects.dt1 中,位于 (31, 21) 的 seq 29 瓦片内部:

  • 右上角包含前车篷布的三角形后翼与支柱;
  • 左下角包含后车平板拖车的前部箱体。
    两者画在同一张 96×288 的 DT1 贴图内,其高低落差是暴雪美术在 1999 年渲染 3D 模型时固化在贴图中的,没有任何外部位移公式能够改变同一瓦片内部像素的相对位置。

4. 数学证明:minBlockY 并不导致 32px 错位

虽然 q27 的 minBlockY = -224 而 q28/q29 为 -256,但在引擎渲染流水线中:

  • 解码器在生成位图缓冲时平移了 yOffset = -minBlockY;
  • 绘制逻辑中基底定位加了 draw.y = orthoY + minBlockY + 80;
  • 屏幕绝对坐标为 screen_y = draw.y + yOffset + block.y = orthoY + 80 + block.y。
    minBlockY 在代数上被完全消去,实际像素的绝对行号完全取决于网格基线与 DT1 block 的原始相对高度,相邻瓦片之间不存在所谓的 32px 阶梯位移。实测 q28 与 q29 的接缝处像素颜色和线条均严格 100% 连续对齐。

综上所述,当前 d2web 的渲染算法与暗黑破坏神 II 原版完全一致,无需调整定位锚点。

经过对暴雪原版资源数据(TownN1.ds1、Objects.dt1)、D2MOO 反编译源码以及 win_ds1edit(Paul Siramy)引擎的比对验证,**该现象并非渲染错位 Bug,而是原版的美术设计(Works as Intended)**。 ### 1. 道具本体是一列“双节车队”,而非单一篷车 该道具并不是一辆被截断的大篷车,而是由两节车厢构成的车队: - **前车(q26 ~ q28 及 q29 右上)**:带圆拱形高顶帆布篷的大货车(含牵引杆、前部大木轮、后部大木轮); - **后车(q29 左下 及 q30)**:挂在后方的四轮低矮平板货运拖车(上面放有盖着低矮灰布的板条箱,尾部装有 3 个木桶)。 因为后方拖车的货物箱上也盖有一层灰白色防雨布,容易从视觉上误以为那是“塌陷下去的后段车篷”。 ### 2. 附件截图对象混淆 Issue 附件中的参考图 `10mceml002at0.png` 实际上是**营地西北侧基德(Gheed)的赌博货摊大篷车**(带条纹遮阳篷和货架柜台),属于完全不同的另一个独立道具模型,并非南部的这列运输车队。 ### 3. 数据层面的硬编码铁证 在 `Objects.dt1` 中,位于 (31, 21) 的 `seq 29` 瓦片内部: - 右上角包含前车篷布的三角形后翼与支柱; - 左下角包含后车平板拖车的前部箱体。 两者画在**同一张 96×288 的 DT1 贴图内**,其高低落差是暴雪美术在 1999 年渲染 3D 模型时固化在贴图中的,没有任何外部位移公式能够改变同一瓦片内部像素的相对位置。 ### 4. 数学证明:`minBlockY` 并不导致 32px 错位 虽然 `q27` 的 `minBlockY = -224` 而 `q28/q29` 为 `-256`,但在引擎渲染流水线中: - 解码器在生成位图缓冲时平移了 `yOffset = -minBlockY`; - 绘制逻辑中基底定位加了 `draw.y = orthoY + minBlockY + 80`; - 屏幕绝对坐标为 `screen_y = draw.y + yOffset + block.y = orthoY + 80 + block.y`。 `minBlockY` 在代数上被完全消去,实际像素的绝对行号完全取决于网格基线与 DT1 block 的原始相对高度,相邻瓦片之间不存在所谓的 32px 阶梯位移。实测 `q28` 与 `q29` 的接缝处像素颜色和线条均严格 100% 连续对齐。 综上所述,当前 `d2web` 的渲染算法与暗黑破坏神 II 原版完全一致,无需调整定位锚点。
Author
Owner

独立复核:结论正确,我按证据逐条确认(不改代码)

我用"只画这四块瓦片、背景全洋红"的离线合成做验证,两条硬证据都成立。

① 是"两节车队",不是一辆车被截断 —— 成立

只画瓦片的车队合成(洋红=无瓦片处)

去掉地板与所有其它道具后可以看清:右侧是一辆带圆拱高顶帆布篷的大货车(车斗、前后大木轮、牵引杆齐备),
左下方是挂在后面的低矮平板拖车(平板+木桶+盖布的板条箱)。拖车货物上的灰白防雨布确实容易被读成
"塌下去的后段车篷"。我此前把它当成"一辆车裂成两块"是误判。

② 同一张瓦片内部就画了两辆车的部件 —— 成立

五块瓦片各自单独导出(左→右 = cell (31,18)…(31,22))

Objects.dt1 里 (31,21) 用的 seq 29(96×288)单张内部上方是前车篷布的后翼、下方是拖车前部箱体;
(31,22) 的 seq 30 则是拖车尾部(木桶/板条箱)。也就是说两车的相对高低是 1999 年烘焙进同一张贴图的,
不存在任何外部位移公式可以改变同一瓦片内的像素关系 —— 与你的判断一致。

③ minBlockY 在代数上被消去 —— 成立,且与我的推导一致

解码时 yOffset = -minBlockY、绘制时 draw.y = orthoY + minBlockY + 80,屏幕行号
screen_y = draw.y + yOffset + block.y = orthoY + 80 + block.y。我先前说的"32px 台阶"只是对美术内容的描述
(q27 的 minBlockY=-224 与 q28/q29 的 -256 恰好差一个块高),不是位移错误的证据 —— 这点我认错误判。

补充一个我做的接缝量化:把车队 4 块合成后做 3×3 闭运算找"内部 1px 空洞",共 186 个像素,但只有 27 个落在瓦片矩形边界 2px 内,
其余散布在绳结、轮辐、板条之间(属于美术自身的 1px 缝隙),没有形成沿接缝的连续缝线 → 与"相邻瓦片内容严格对齐"一致。

④ 附件那张参考图是另一个道具 —— 与我的实测自洽

我把经典版 MPQ 里全部 265 个 DT1 按"亮像素占比+宽条纹段"扫过:没有任何条纹棚布瓦片
(最亮的是 Act 5 攻城场景的雪崖)。所以参考图里的条纹遮阳篷不可能来自 DT1 —— 只能是对象(DCC)美术,
与你判断的"基德(Gheed)赌博货摊"属于另一个独立道具完全一致。

⑤ 由此得到的一条真实遗留项(与本 issue 无关,另记)

真正让我们营地和原版看起来不同的,是对象层整体没画:本项目只解析对象的位置与美术成员元数据
(营地 26 个对象:19 个火把、传送点、NPC、TA/DC/B6),静态帧尚未接入。参考图里的条纹篷、火把、木箱、
木桶、地毯、NPC 都属于这一层。建议单独开 issue 跟踪"对象静态帧渲染",本 issue 可按 Works as Intended 关闭。

## 独立复核:结论**正确**,我按证据逐条确认(不改代码) 我用"只画这四块瓦片、背景全洋红"的离线合成做验证,两条硬证据都成立。 ### ① 是"两节车队",不是一辆车被截断 —— 成立 ![只画瓦片的车队合成(洋红=无瓦片处)](https://git.projectdiablo2.cn/attachments/a2b7db54-451c-48f6-99d6-236a37908780) 去掉地板与所有其它道具后可以看清:右侧是一辆**带圆拱高顶帆布篷的大货车**(车斗、前后大木轮、牵引杆齐备), 左下方是**挂在后面的低矮平板拖车**(平板+木桶+盖布的板条箱)。拖车货物上的灰白防雨布确实容易被读成 "塌下去的后段车篷"。我此前把它当成"一辆车裂成两块"是**误判**。 ### ② 同一张瓦片内部就画了两辆车的部件 —— 成立 ![五块瓦片各自单独导出(左→右 = cell (31,18)…(31,22))](https://git.projectdiablo2.cn/attachments/8fa2c36b-8257-49f5-b72e-eeca94658d3a) `Objects.dt1` 里 (31,21) 用的 `seq 29`(96×288)单张内部**上方是前车篷布的后翼、下方是拖车前部箱体**; (31,22) 的 `seq 30` 则是拖车尾部(木桶/板条箱)。也就是说两车的相对高低是 1999 年烘焙进同一张贴图的, **不存在任何外部位移公式可以改变同一瓦片内的像素关系** —— 与你的判断一致。 ### ③ `minBlockY` 在代数上被消去 —— 成立,且与我的推导一致 解码时 `yOffset = -minBlockY`、绘制时 `draw.y = orthoY + minBlockY + 80`,屏幕行号 `screen_y = draw.y + yOffset + block.y = orthoY + 80 + block.y`。我先前说的"32px 台阶"只是**对美术内容的描述** (`q27` 的 `minBlockY=-224` 与 `q28/q29` 的 `-256` 恰好差一个块高),不是位移错误的证据 —— 这点我认错误判。 补充一个我做的接缝量化:把车队 4 块合成后做 3×3 闭运算找"内部 1px 空洞",共 186 个像素,但**只有 27 个落在瓦片矩形边界 2px 内**, 其余散布在绳结、轮辐、板条之间(属于美术自身的 1px 缝隙),**没有形成沿接缝的连续缝线** → 与"相邻瓦片内容严格对齐"一致。 ### ④ 附件那张参考图是另一个道具 —— 与我的实测自洽 我把经典版 MPQ 里**全部 265 个 DT1** 按"亮像素占比+宽条纹段"扫过:**没有任何条纹棚布瓦片** (最亮的是 Act 5 攻城场景的雪崖)。所以参考图里的条纹遮阳篷不可能来自 DT1 —— 只能是**对象(DCC)美术**, 与你判断的"基德(Gheed)赌博货摊"属于另一个独立道具完全一致。 ### ⑤ 由此得到的一条真实遗留项(与本 issue 无关,另记) 真正让我们营地和原版看起来不同的,是**对象层整体没画**:本项目只解析对象的位置与美术成员元数据 (营地 26 个对象:19 个火把、传送点、NPC、`TA`/`DC`/`B6`),静态帧尚未接入。参考图里的条纹篷、火把、木箱、 木桶、地毯、NPC 都属于这一层。建议单独开 issue 跟踪"对象静态帧渲染",本 issue 可按 **Works as Intended** 关闭。
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#1
No description provided.