9

我正在用六边形瓷砖制作游戏,并决定使用三角形/六边形网格。我发现这个问题帮助我生成坐标,并稍微修改了代码以将所有坐标作为键存储在字典中,其值为“。” (地板)或“X”(墙),并包含一个函数,该函数打印出地图的字符串表示形式,其中每个非空白字符代表一个六边形瓷砖。这是新代码:

deltas = [[1,0,-1],[0,1,-1],[-1,1,0],[-1,0,1],[0,-1,1],[1,-1,0]]
class HexGrid():
    def __init__(self, radius):
        self.radius = radius
        self.tiles = {(0, 0, 0): "X"}
        for r in range(radius):
            a = 0
            b = -r
            c = +r
            for j in range(6):
                num_of_hexas_in_edge = r
                for i in range(num_of_hexas_in_edge):
                    a = a+deltas[j][0]
                    b = b+deltas[j][1]
                    c = c+deltas[j][2]           
                    self.tiles[a,b,c] = "X"

    def show(self):
        l = []
        for y in range(20):
            l.append([])
            for x in range(60):
                l[y].append(".")
        for (a,b,c), tile in self.tiles.iteritems():
            l[self.radius-1-b][a-c+(2*(self.radius-1))] = self.tiles[a,b,c]
        mapString = ""
        for y in range(len(l)):
            for x in range(len(l[y])):
                mapString += l[y][x]
            mapString += "\n"
        print(mapString)

使用此代码,我可以生成半径内的所有坐标,如下所示:

import hexgrid
hg = hexgrid.HexGrid(radius)

并访问这样的坐标:

hg.tiles[a,b,c]

现在这似乎工作正常,但我确信以这种方式存储地图一定有一些缺点。如果有任何缺点,您能否指出它们,并提出更好的存储地图的方法?非常感谢您的时间。

4

4 回答 4

14

使用数组进行存储可能会节省一些 CPU 时间,但差异可能可以忽略不计。

但是,您错过了管理此类地图的一种非常简单的方法。将其视为行和列,只是单元格的形状略有不同。

+--+--+--+--+--+--+--+
 \/ \/ \/ \/ \/ \/ \/    Even row

  /\ /\ /\ /\ /\ /\ /\   Odd row
 +--+--+--+--+--+--+--+

或者对于六边形:

  __    __    __    __
 /  \__/  \__/  \__/  \__ Even row
 \__/  \__/ A\__/  \__/   Odd  row
 /  \__/ F\__/ B\__/  \__ Even row
 \__/  \__/ X\__/  \__/   Odd  row
 /  \__/ E\__/ C\__/  \__ Even row
 \__/  \__/ D\__/  \__/   Odd  row
 /  \__/  \__/  \__/  \__ Even row
 \__/  \__/  \__/  \__/   Odd  row

然后,您可以将数据存储为常规二维数组。奇数行向右偏移 0.5,您需要计算X: above: A = (0,-2)、up right: B = (1,-1)、bottom right: C = (1,1)、 below: D = (0,2),bottom left: E = (0,1)、top left: 的邻接步骤:F = (0,-1)

如果您可以浪费一点内存,您也可以将其他每一列都留空,这样邻域关系就会变得更简单:(0,-2), (1,-1), (1,-1), (0,-2), (-1,-1), (-1,1)

于 2012-07-07T08:41:56.503 回答
7

我也做了一些研究,并找到了一种更简单的方法来做到这一点。你不必变得像你一样复杂!该表可以是一个简单的数组数组,没有任何特殊规则。

您想使用六角根坐标系。请参阅此处的理论:https ://en.wikipedia.org/wiki/Root_system 。还有https://www.redblobgames.com/grids/hexagons/

单元格 (0,0) 位于结构的中心,因此它有六个邻居:如众所周知的正交表 (1,0)、(0,1)、(-1,0)、(0 ,-1) 还有 (1,1) , (-1-1)。其他单元格同样有六个邻居,不需要取模!

这里有一些 Ascii 艺术以便更好地理解:

   _____       _____      ____      __
  / -2,2\_____/ 0,1 \____/2,0 \____/  \__ 
  \_____/-1,1 \_____/ 1,0\____/3,-1\__/   
  /-2,1 \_____/0,0  \____/2,-1\____/  \__     
  \_____/-1,0 \_____/1,-1\____/3,-2\__/   
  /-2,0 \_____/ 0,-1\____/2,-2\____/  \__ 
  \_____/     \_____/    \____/    \__/   

您可以计算平面中每个单元格中心的位置(以及屏幕中的位置),因为它遵循矢量几何规则。向量的坐标是 60° 而不是 90°:a=(0,1) 但 b=(0,87,0.5),只需将这些坐标相乘并相加!

您可能想要使用 python 库Hexy

于 2018-02-02T22:46:12.007 回答
0

不要使用 hg.tiles[a,b,c]。

通过这种方式使磁贴成为一个三维列表, hg.tiles = [[[z for z in range(10)] for y in range(10)] for x in range(10)] 现在您可以使用hg.tiles[a][b][c]

PS:其他作业a = a+deltas[j][0]应该a += deltas[j][0]以此类推

于 2012-07-07T08:20:33.463 回答
0

也许存储十六进制的最佳方式是在 python 列表或元组中;然后挑战变成如何从您的列表中检索特定的十六进制。在 python 中,一个很好的方法是构建一个十六进制坐标字典作为键,列表索引(或十六进制对象)作为值。假设您的十六进制列表不需要更改,则列表可以在完成后转换为元组。如果您将十六进制对象作为值保存在字典中,则可以完全放弃保存列表;字典直接将十六进制坐标映射到对象。

您的代码已经生成了一系列十六进制坐标,只需将它们保存在列表中并同时构建您的参考字典。此外,如果您正在编写一个类来管理您的游戏板,则存储和检索的所有细节都可以隐藏在该类中。

一些代码:

radius = 4
deltas = [[1,0,-1],[0,1,-1],[-1,1,0],[-1,0,1],[0,-1,1],[1,-1,0]]

hexes = []
indices = {}
index = 0

for r in range(radius):
    print("radius %d" % r)
    x = 0
    y = -r
    z = +r

    hexes.append((x,y,z))
    indices[(x,y,z)] = index   # Or store objects here
    index += 1
    print(x,y,z)

    for j in range(6):
        if j==5:
            num_of_hexes_in_edge = r-1
        else:
            num_of_hexes_in_edge = r
        for i in range(num_of_hexes_in_edge):
            x = x+deltas[j][0]
            y = y+deltas[j][1]
            z = z+deltas[j][2]

            hexes.append((x,y,z))
            indices[(x,y,z)] = index   # Or store objects here
            index += 1
            print(x,y,z)

hexes = tuple(hexes)
print(hexes)
print(indices)
于 2019-02-23T00:00:47.707 回答