存储十六进制网格


10

我一直在为Unity3D创建一个小的十六进制网格框架,并遇到了以下难题。这是我的坐标系(从此处获取):

在此处输入图片说明

除了我不知道如何存储外,所有这些都很好地工作。我最初打算将其存储在2D数组中,并使用图像生成我的地图。

一个问题是它具有负值(可以通过稍微偏移坐标来轻松解决此问题)。

但是,由于坐标系的原因,此类图像或位图必须是菱形的-并且由于这些结构是方形的,因此即使我一起砍东西,也会造成很多麻烦。我有什么可以解决的问题吗?我记得在统一论坛上看到过与此相关的论坛帖子,但我找不到链接。

在这里编写一组坐标翻译器是最好的解决方案吗?

如果你们认为这会有所帮助,我可以张贴代码和问题图像。


1
您是否只能保存六边形透明的PNG图像?
Markus von Broady 2012年

我保存到png和数组的主要问题是它们必须包含的“空白”数量,以保持此坐标系完整。
PeeC 2012年

1
如果“空白”表示透明像素,那么为什么它的数量有问题?
Markus von Broady

这是非常好的一点。大多数图像格式不会浪费太多的内存来存储重复的图案。但是,仍然有点烦我要存储此地图,因为我使用了这么多的内存(灰色像素是空白空间,其他颜色是有效的十六进制坐标)。
PeeC 2012年

1
哦,您存储的是网格数据,而不是图块图像!为什么不只将数据结构(网格)保存到二进制文件,又不使用JSON编码并保存到文本文件呢?我不知道Unity的功能。另外,您可能要确认这一点,但是我相信以PNG格式优化(松散压缩)相同颜色的区域。
Markus von Broady,2012年

Answers:


9

您正在使用的平行四边形坐标更易于使用,但是它们的确存在对矩形地图很奇怪的缺点。一种方法是将其与偏移坐标一起存储,但实际上在游戏逻辑中使用平行四边形坐标。

观察:在地图的每一行中,网格数据是连续的。所有浪费的空间都在左侧和右侧。

解决方案:在该行中,存储数据从最左边的列开始,而不是从标记为0的列开始。计算坐标系中矩形地图的第一列,然后从列坐标中减去该列以确定在数组中的位置。这也适用于负列坐标。

在地图的getter和setter中执行转换,如下所示:

inline function get(q, r) {
    first_column_in_this_row = -floor(q/2);
    return array[r][q - first_column_in_this_row];
}

您必须修改此设置才能使用您选择的坐标和地图(请注意一个差异)。在某些布局中,您将需要按行偏移列,而不是相反。

您可以使用相同的技巧制作其他形状的地图。它不仅限于矩形。

如果您使用的是C或C ++,则可以使用指针算法来加快速度。代替存储指向数组的指针数组,而是存储已由调整的指针数组first_column_in_row。(这可能不是便携式的)


据我所知,这是可行的,但是数学确实很奇怪。在尝试了一些对我很有意义的方程式之后,我yIndex = y-((x%2==0)?(x/2-x):(-x/2)-1)经过反复尝试后决定接受。不知道它是如何工作的。
PeeC 2012年

做那个yIndex = y-((x%2==0)?(-x/2):(-x/2)-1)。x / 2都是基于整数的顺便说一句,因此无需限制。
PeeC 2012年

6

就个人而言,我更喜欢简单而不是节省内存。在需要之前不要优化!

如果您仍然想节省一些字节,请按以下步骤操作:

在此处输入图片说明

  1. 将平行四边形切成两半,形成两个直角三角形
  2. 重新排列两个三角形以形成一个矩形。
  3. (请注意,我添加了绿色缓冲带,因此计算效果很好。)

将矩形坐标映射到平行四边形坐标并返回的Python代码:

# Height of rectangle
H = 15

def r2p(x, y):
"rectangle to parallelogram"
if y < -x/2 + H:
    y = y + H
return (x - 1, y)

def p2r(x,y):
"parallelogram to rectangle"
if y >= H:
    y = y - H
return (x + 1, y)

2
你也可以只移动像素垂直向下-这将是在图像上offsetY = Math.floor ( (x+1)/2 )
马库斯·冯·布罗迪

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.