六边形网格通常用于战棋类游戏,目的是提供比四边形地图更平滑的距离体验(尤其是圆看起来更像圆了)。关于他的好处和坏处我不想多说,通常来讲,大家会认为他的计算复杂度要远高于四边形地图。
实际上大多数的六边形地图看起来是这样:
1,1 --- 2,1 --- 3,1 --- 4,1
--- 1,2 --- 2,2 --- 3,2 --- 4,2
1,3 --- 2,3 --- 3,3 --- 4,3
--- 1,4 --- 2,4 --- 3,4 --- 4,4
这确实使得我们在距离计算上出现了一些麻烦(有兴趣的朋友可以自行推导距离公式)
但是最近我发现,如果我们改变一下坐标排布,那么很多事情会变得简单起来
(当然,虽然大多数市面上游戏都是上面这样显示的,但他们底层的算法并不公开,所以不能说明他们的坐标系就是这么设计的,但三国志11显示了每个格子的坐标,这使得我常年以来是按照他的方式去设计坐标系的,也许更多游戏早就采用了我下面所说的方法吧)
当我尝试着将坐标系调整成:
1,1 --- 2,1 --- 3,1 --- 4,1
--- 1,2 --- 2,2 --- 3,2 --- 4,2
--- --- 1,3 --- 2,3 --- 3,3 --- 4,3
--- --- --- 1,4 --- 2,4 --- 3,4 --- 4,4
我惊讶的发现,距离公式变成了
d = min( dx+dy, max(dx, dy))
其中dx,dy分别是两点x,y坐标差的绝对值(实际上,两点连线斜率为负时,是max(dx,dy),否则是dx+dy)
这使得很多计算变得简单了,而且在这种排布中,我们共有三条简单的直线:x = k,y=k,x+y=k(在老的排布中,x=k要换成x-y=k)
遍历临近单元格的步骤也更清晰:
考虑距离x,y为r的格子,他们的坐标满足
x' = x-r, y' = y+0 ~ y+r
x' = x+r, y' = y-0 ~ y-r
y' = y-r, x' = x+0 ~ x+r
y' = y+r, x' = x-0 ~ x-r
x' = x'+1~ x'+(r-1), y' = y'+(r-1) ~ y'+1
x' = x'-1~ x'-(r-1), y' = y'-(r-1) ~ y'-1
这样的六段遍历
如果想要遍历r以内的单元格则更简单,单纯的按照四边形遍历法的二重循环,加上一个附加条件i+j >= x+y-r && i+j <= x+y+r即可
唯一的问题在于,这样的地图看起来是平行四边形而不再是长方形,这使得我们需要对地图进行一个预裁剪,将某些格子标记为边界外,但这个小小的不便远远无法抵消中间大量计算的简化。更何况,如果想做文明那样的环形地图,甚至不需要裁剪,因为平行四边形本身就可以完美自拼接