技术求助:这两个游戏坐标转换函数是否互为逆函数?
地图空间与屏幕空间坐标转换函数的逆函数问题
这两个函数并非严格互为逆函数,运算顺序、偏移量的缩放匹配以及tileSize的处理逻辑都存在错位,直接导致反向转换失效。
问题拆解:先理清正转换(ShrinkPos)的逻辑
把ShrinkPos的运算步骤整理成数学表达式(假设输入pos是地图空间坐标(Mx, My),输出是屏幕空间坐标(Sx, Sy),C代表Globals.currentCampLocation,T代表tileSize,O代表offset):
- 临时坐标偏移:
newPos = (Mx + Cx +10, My + Cy +10) - 缩放加tile偏移:
Sx = newPos.X/scale + 2*Tx/scale;Sy = newPos.Y/scale + Ty/scale - 减去offset缩放值:
Sx = Sx - 2*Ox/scale;Sy = Sy - Oy/scale
合并后最终的正转换公式:
Sx = (Mx + Cx + 10 + 2*Tx - 2*Ox) / scale Sy = (My + Cy + 10 + Ty - Oy) / scale
原反向函数(ExpandPos)的错误点
原ExpandPos完全没有对应正转换的逆过程:
- 第一步错误地用屏幕坐标直接减去营地坐标和固定偏移,和正转换的第一步逻辑反向错位
- tileSize和offset的缩放系数(比如
(tileSize.X * scale)/2)和正转换中的2*Tx/scale完全不匹配 - 整体运算顺序颠倒,未按照正转换的步骤逆推
修正后的反向转换函数
从正转换公式反向推导,得到地图坐标的计算方式:
Mx = Sx * scale - Cx - 10 - 2*Tx + 2*Ox My = Sy * scale - Cy - 10 - Ty + Oy
对应的C#代码:
public Point ExpandPos(int scale, Point pos) { Point mapPos = new Point(); mapPos.X = pos.X * scale - Globals.currentCampLocation.X - 10 - (tileSize.X * 2) + (offset.X * 2); mapPos.Y = pos.Y * scale - Globals.currentCampLocation.Y - 10 - tileSize.Y + offset.Y; return mapPos; }
额外注意点
如果scale、tileSize、offset都是整数类型,正转换中的除法会存在截断精度损失,转换→逆转换后可能无法完全还原原始坐标(比如地图坐标11,scale为2,正转换后得到5,逆转换后得到10)。若需要更高精度,可考虑用浮点类型中转后再转成整数。
内容的提问来源于stack exchange,提问作者Finch Youngs
相关产品推荐
相关产品推荐

