我正在用六角形瓷砖制作游戏,并决定使用三角形/六边形网格。我发现this问题帮助我生成坐标,并稍微修改了代码,将所有坐标存储为字典中的键,其值为“。”。 (floor)或“X”(wall,)并包括一个打印出地图的字符串表示的函数,其中每个非空白字符代表一个六边形图块。这是新代码:
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]
这似乎现在工作正常,但我确信以这种方式存储地图肯定存在一些缺点。如果有任何缺点,请指出它们,并提出更好的存储方式?非常感谢你的时间。
答案 0 :(得分:10)
使用数组存储可能会节省一些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
然后,您可以将数据存储为常规2D数组。奇数行向右偏移.5,您需要确定X
的邻居步骤:上方:A = (0,-2)
,右上方:B = (1,-1)
,右下角:{{1} },下方:C = (1,1)
左下角:D = (0,2),
,左上角:E = (0,1)
如果你可以浪费一点内存,你也可以将其他列留空,邻居变得更简单:F = (0,-1)
答案 1 :(得分:1)
我也做了一些研究,发现了一种更为简单的方法。你不必像你那样复杂!该表可以是一个简单的数组数组,没有任何特殊规则。
您想使用六边形根协调系统。请参阅此处的理论: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),只需乘以并加上这些坐标!
您可能想要使用pyhton librairy Hexy:https://github.com/RedFT/Hexy
答案 2 :(得分: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]
,依此类推其他作业
答案 3 :(得分: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)