热血传奇地图本质是一套基于等轴测(斜45度)网格的 Tilemap 系统,逻辑坐标单元固定映射为 48×32 像素的菱形/矩形瓦片,由 .map 索引文件驱动 Tiles.wil、SmTiles.wil、Objects.wil 三组补丁完成分层合成 。绘制不平滑的根本原因不在算法错误,而在离散整数坐标 + 无亚像素插值 + 建筑基点反转 + 大地砖奇偶对齐约束 这四者耦合导致的采样失真 。
一、Tile 数据结构与三层合成模型
每张 .map 文件 = 52字节头(宽、高、标题、更新时间、保留位)+ wWidth×wHeight 个 TMapInfo 记录;每条记录给出三层索引:
- wBkImg / wBigTileImg → Tiles 大地砖(最底层,96×64 像素,覆盖 2×2 逻辑坐标)
• wMidImg / wSmTileImg → SmTiles 小地砖(中间层,48×32 像素,1 逻辑坐标)
- wFrImg / wObjImg → Objects 遮挡层(顶层,宽 48、高不限,山体/房屋/树木,承载人物半透明遮挡)
引擎启动场景时按摄像机视锥算出可见坐标范围,逐格查索引 → 解 Wil 包 → 取到 BGR/A 像素块 → 按层级从下往上 Blit 到后备缓冲,再翻页到屏幕 。
二、标准绘制循环(以 TPlayScene.PlayScene 为基准)
1. 由摄像机逻辑坐标 (CamX,CamY) 换算屏幕起点,可见列数 = ScreenWidth÷48 + 2,行数 = ScreenHeight÷32 + 2;
2. 外层循环 Y:for nY := -2 to ScreenHeight div 32 + 16 do(盟重石墓等大模型需循环约两倍屏高,否则房屋下半截丢失) ;
3. 内层循环 X:取当前格 TMapInfo;
4. 第一遍判定:若纹理尺寸 == 48×32 → 直接画小地砖;
5. 第二遍判定:若坐标触发混合(大地砖跨界、动画帧、灯光混合)→ 走混合分支;
6. 画 Objects 层时执行 Y 轴翻转 + 左下角基点偏移(见下文);
7. 最后画角色、特效、UI 。
三、坐标基点反转与房屋绘制坑点
传奇沿用数学坐标系(Y 向上),屏幕坐标系 Y 向下,建筑类 Object 以“左下角”为锚点而非左上角 。
后果:一张长度接近屏宽的房屋,取索引时必须向上多循环一倍屏高;循环边界只写 ScreenHeight div 32 就会出现房屋下半截断、门框悬空。修正写法:
for nY := -2 to (ScreenHeight div 32) + 16 do 或统一按 Object 实际高度向上回溯若干行再绘制 。
四、大地砖 2×2 对齐约束(核心平滑障碍)
逻辑坐标单元 48×32,大地砖 96×64 = 正好 2×2 坐标单元 。引擎规则:当渲染起始 (X,Y) 不是 2 的倍数时,直接跳过该大地砖不画,造成地面“缺块、跳格、硬边”。
正确做法二选一:
- 绘制前把起始坐标向下取整到最近偶数:StartX := StartX and not 1; StartY := StartY and not 1; 再扩一圈渲染;
• 或强制地图编辑阶段所有大地砖铺设坐标保持偶数对齐,map 文件里 BkImg 只挂在偶偶格上 。
五、为何看起来“不平滑”——失真来源拆解
• 整数坐标步进:摄像机微移 1px 也按整格重取,边缘出现像素跳动;
• 无双线性/各向异性过滤:DirectX7/8 时代默认最近邻采样,48×32 块边界呈硬锯齿;
- 比例 48:32 = 3:2 为等轴测压缩经验值,非真实透视,斜向拉长感强;
• 大地砖奇偶跳过 → 地面纹理断裂;
• Object 基点反转 → 建筑与地面接缝错位 。
六、平滑绘制改进方案(离屏预合成法)
思路:建一个比屏幕大 2~4 个 Tile 的 RenderTarget(如屏 800×600 → RT 896×664),把可见区外扩一圈全部 Tile 先画进 RT,再做一次整体 Blit 到主表面 。
步骤:
1. 创建 RT:宽 = ScreenW + 2×48,高 = ScreenH + 2×32;
2. 摄像机起始坐标取整到偶偶,循环范围上下左右各扩 1~2 格;
3. 大地砖、小地砖、Object、灯光全部画进 RT;
4. 开启线性过滤(D3DTEXF_LINEAR)或手动做相邻 Tile 边缘平均;
5. RT → BackBuffer 用 BitBlt/StretchRect,摄像机偏移量做亚像素平移;
6. 灯光混合、阴影、动画帧统一在 RT 内合成,避免逐帧重遍历地图 。
效果:消除摄像机移动时的 Tile 闪烁、缺块,大地砖奇偶跳格被外扩环覆盖,边缘可做 1px 平均过渡。
七、美术侧无缝拼接配合(编辑器层)
即便引擎改了,素材本身硬边也会糊:
• 大地砖 96×64、小地砖 48×32 画布用 PS “滤镜→其他→位移”(小砖 -24/-16,大砖 -48/-32)暴露接缝,仿制图章修补;
• 两款大地砖拼接处裁切互融,用渐变/柔光做过渡砖;
- 参考线按 24×16 等分,保证 4 象限纹理连续;
• OBJ 层高度不超 896px,避免闪烁;地图边缘封边参考 12×12 限制格 。
八、常见绘制异常归位
• 地面缺大块 → 起始 X/Y 非偶数,未向下取整;
- 房屋下半消失 → Y 循环未加倍屏高,基点反转未补偿;
• 移动时地块闪 → 未用外扩 RT,逐帧按整格重取;
• 斜角锯齿重 → 未开线性过滤且素材硬边;
• 建筑与地面错位 → Object 绘制未做 Y 翻转 + 左下锚偏移 。
整套机制落在“整数等轴测网格 + Wil 索引解包 + 三层 Blit + 奇偶对齐限制”上,平滑化不是换算法,而是用离屏 RT 外扩预合成 + 偶数对齐 + 线性采样把离散台阶压成连续视口。
热血传奇Tile瓦片地图绘制机制解析与平滑渲染修正方案详述
来源:
作者:
点击:

