奇数行偏移半瓦矩形等距网格鼠标坐标转网格坐标方法
奇数行偏移半瓦的矩形等距网格 鼠标坐标转网格坐标方案
首先统一定义用到的固定参数,避免公式匹配出错:
- 单块菱形瓦片的总宽度记为
tileW,总高度记为tileH(常规等距美术资源一般满足tileW = 2 * tileH,比如宽64像素、高32像素) - 屏幕坐标采用图形学通用规则:原点在画布左上角,x轴向右递增,y轴向下递增
- 网格原点在
(0,0)号瓦片的最顶端顶点 - 排布规则:行号从0开始计数,偶数行无横向偏移,奇数行整体向右偏移
tileW/2(半块瓦宽度),相邻两行的垂直间距为tileH/2,和标准等距网格一致
直接计算公式版(性能最优,适合大规模网格)
你之前用的标准菱形等距仿射变换只需要加一步奇偶行偏移修正就能用,步骤如下:
- 先代入标准等距逆变换公式,用鼠标原始屏幕坐标
(mouseX, mouseY)算出临时浮点坐标:halfW = tileW / 2 halfH = tileH / 2 tempCol = (mouseX / halfW + mouseY / halfH) / 2 tempRow = (mouseY / halfH - mouseX / halfW) / 2 roughRow = floor(tempRow) - 根据粗算得到的行号
roughRow做偏移修正,得到最终列号:if roughRow % 2 == 1: // 奇数行整体右移了半瓦,计算列号时先把鼠标x坐标左移半瓦抵消偏移 adjustedX = mouseX - halfW finalCol = floor( (adjustedX / halfW + mouseY / halfH) / 2 ) else: // 偶数行无偏移,直接取临时列的整数部分即可 finalCol = floor(tempCol) finalRow = roughRow - (可选边界校验)算完
(finalCol, finalRow)之后,只需要额外校验该瓦片、以及它相邻的1个边界瓦片(最多2个候选),做点是否在菱形内的判断,就能覆盖所有边缘像素的计算误差,性能损耗可以忽略。
碰撞兜底版(零公式误差,逻辑无调试成本)
如果不想处理公式的边界特例,可以用极低计算量的碰撞判定思路,完全不需要推导复杂变换,逻辑100%适配该类排布规则:
- 先圈定候选瓦片范围:因为瓦片排布密度固定,鼠标点最多只会和2个瓦片相交,不需要遍历全网格
- 先算鼠标y坐标覆盖的行:每行垂直占
halfH高度,候选行就是floor(mouseY / halfH)以及它上下相邻的1行(注意过滤掉小于0、超出网格最大行的无效值) - 对每个候选行,根据行奇偶算横向偏移:偶数行偏移0,奇数行偏移
halfW,再算该行内可能命中的列:每块瓦占tileW宽度,候选列就是floor( (mouseX - rowOffset) / tileW )以及左右相邻的1列(同样过滤超出网格范围的无效值)
- 先算鼠标y坐标覆盖的行:每行垂直占
- 遍历所有候选瓦片(最多4个,绝大多数场景只有2个),逐个判断鼠标点是否落在瓦片的菱形范围内,第一个命中的就是目标网格单元。
菱形点碰撞判定非常简单,不需要复杂多边形算法:先算出鼠标点相对于当前瓦片中心的局部坐标
(localX, localY),只要满足abs(localX)/halfW + abs(localY)/halfH <= 1,就说明点在该菱形瓦片内部。
之前两种方案失效的核心原因很明确:纯菱形网格适配逻辑、标准仿射变换都是针对「行列按固定步长双向交错」的标准菱形等距网格设计的,而你用的网格是「仅奇数行单向偏移半瓦、列方向按矩形对齐」的特殊排布,直接套无偏移的变换矩阵自然会出现固定的列号偏差。
内容的提问来源于stack exchange,提问作者Darkzaelus
相关产品推荐
相关产品推荐

