說我要建一個棋盤遊戲與hextile格,像Settlers of Catan:如何在內存中表示六邊形/十六進制網格?
注意,每個頂點和邊可能有一個屬性(道路和結算以上)。
我該如何製作代表這塊電路板的數據結構?訪問每個瓦片的鄰居,邊緣和頂點的模式是什麼?
說我要建一個棋盤遊戲與hextile格,像Settlers of Catan:如何在內存中表示六邊形/十六進制網格?
注意,每個頂點和邊可能有一個屬性(道路和結算以上)。
我該如何製作代表這塊電路板的數據結構?訪問每個瓦片的鄰居,邊緣和頂點的模式是什麼?
Amit Patel發佈了一個令人驚歎的關於此主題的頁面。它是如此全面而精彩的,它必須是明確的回答這個問題:Hexagonal Grids
這種網格可以以二維陣列來表示:
如果
2
7 3
1
6 4
5
與它在十六進制網格鄰居的數目之一,那麼就可以把此成一個二維數組像這樣:
2 3
7 1 4
6 5
顯然鄰居岬不僅由被水平或垂直相鄰而且使用一條對角線在該網格來確定。
但是,如果您喜歡,也可以使用圖表。
2
7 3
1
6 4
5
你也可以嘗試'平'行的地圖。在這個例子中這將是:
2
7 1 3
6 5 4
它有時更多有用的一行行:P
這可能有一些混亂的鄰居檢查代碼,因爲,例如,1和6是鄰居,但3和5不是,但它們具有相同的相對位置。 – Dukeling 2017-07-27 16:12:56
This article經歷如何建立一個異構/六邊形網格遊戲。我建議你看看Forcing Isometric and Hexagonal Maps onto a Rectangular Grid
部分和運動部分。雖然它與你正在尋找的不同,但它可以幫助你制定如何做你想做的事情。
我建議類似如下(我會用Delphi式的聲明):
type
THexEdge = record
Hexes: array[1..2] of Integer; // Index of adjoining hexes.
// Other edge stuff goes here.
end;
THexVertex = record
Hexes: array[1..3] of Integer; // Index of adjoining hexes.
// Other vertex stuff goes here.
end;
THex = record
Edges: array[1..6] of Integer; // Index of edge.
Vertices: array[1..6] of Integer; // Index of vertex.
// Other hex stuff goes here.
end;
var
Edges: array of THexEdge;
Vertices: array of THexVertex;
HexMap: array of THex;
每個十六進制有六個邊和六個頂點。每條邊都跟蹤它的兩個相鄰的格,每個頂點跟蹤它的三個相鄰的格(在地圖邊上的格是特殊情況)。
有很多事情你可以做不同的方式。你可以使用指針而不是數組,你可以使用對象而不是記錄,並且可以像其他回答者所建議的那樣將你的數據庫存儲在一個二維數組中。
希望這可能會給你一些關於處理它的方法。
我已經處理了很多與十六進制。在這種情況下,您可以跟蹤六角形邊界的每個6點。這讓你很容易繪製它。
您將有一個表示對象的單個數組。這些十六進制對象中的每一個還具有指向另一個「邊」陣列的6個「指針」(或另一個數組的索引)。 「頂點」也是一樣。當然,頂點會有3個指向鄰接的六邊形的指針,並且邊有2個。
因此,十六進制可能是這樣的: X,Y,點(6),頂點(6),邊(6)
然後你有一個十六進制數組,頂點數組,側陣列。
然後找到十六進制的頂點/邊,或者其他任何東西都很簡單。
當我說指針時,它可能很容易就是一個指向vertice或side數組或其他元素的整數。當然,數組可以是列表或其他。
我們實施卡坦AI的定居者一類項目,以及修改後的代碼從this答案(這是越野車)創建一個具有恆定時間隨機訪問頂點和邊的板子。這是一個有趣的問題,但董事會花了很多時間,所以如果有人仍在尋找一個簡單的實現這裏是我們的Python代碼:
class Board:
# Layout is just a double list of Tiles, some will be None
def __init__(self, layout=None):
self.numRows = len(layout)
self.numCols = len(layout[0])
self.hexagons = [[None for x in xrange(self.numCols)] for x in xrange(self.numRows)]
self.edges = [[None for x in xrange(self.numCols*2+2)] for x in xrange(self.numRows*2+2)]
self.vertices = [[None for x in xrange(self.numCols*2+2)] for x in xrange(self.numRows*2+2)]
for row in self.hexagons:
for hexagon in row:
if hexagon == None: continue
edgeLocations = self.getEdgeLocations(hexagon)
vertexLocations = self.getVertexLocations(hexagon)
for xLoc,yLoc in edgeLocations:
if self.edges[xLoc][yLoc] == None:
self.edges[xLoc][yLoc] = Edge(xLoc,yLoc)
for xLoc,yLoc in vertexLocations:
if self.vertices[xLoc][yLoc] == None:
self.vertices[xLoc][yLoc] = Vertex(xLoc,yLoc)
def getNeighborHexes(self, hex):
neighbors = []
x = hex.X
y = hex.Y
offset = 1
if x % 2 != 0:
offset = -1
if (y+1) < len(self.hexagons[x]):
hexOne = self.hexagons[x][y+1]
if hexOne != None: neighbors.append(hexOne)
if y > 0:
hexTwo = self.hexagons[x][y-1]
if hexTwo != None: neighbors.append(hexTwo)
if (x+1) < len(self.hexagons):
hexThree = self.hexagons[x+1][y]
if hexThree != None: neighbors.append(hexThree)
if x > 0:
hexFour = self.hexagons[x-1][y]
if hexFour != None: neighbors.append(hexFour)
if (y+offset) >= 0 and (y+offset) < len(self.hexagons[x]):
if (x+1) < len(self.hexagons):
hexFive = self.hexagons[x+1][y+offset]
if hexFive != None: neighbors.append(hexFive)
if x > 0:
hexSix = self.hexagons[x-1][y+offset]
if hexSix != None: neighbors.append(hexSix)
return neighbors
def getNeighborVertices(self, vertex):
neighbors = []
x = vertex.X
y = vertex.Y
offset = -1
if x % 2 == y % 2: offset = 1
# Logic from thinking that this is saying getEdgesOfVertex
# and then for each edge getVertexEnds, taking out the three that are ==vertex
if (y+1) < len(self.vertices[0]):
vertexOne = self.vertices[x][y+1]
if vertexOne != None: neighbors.append(vertexOne)
if y > 0:
vertexTwo = self.vertices[x][y-1]
if vertexTwo != None: neighbors.append(vertexTwo)
if (x+offset) >= 0 and (x+offset) < len(self.vertices):
vertexThree = self.vertices[x+offset][y]
if vertexThree != None: neighbors.append(vertexThree)
return neighbors
# used to initially create vertices
def getVertexLocations(self, hex):
vertexLocations = []
x = hex.X
y = hex.Y
offset = x % 2
offset = 0-offset
vertexLocations.append((x, 2*y+offset))
vertexLocations.append((x, 2*y+1+offset))
vertexLocations.append((x, 2*y+2+offset))
vertexLocations.append((x+1, 2*y+offset))
vertexLocations.append((x+1, 2*y+1+offset))
vertexLocations.append((x+1, 2*y+2+offset))
return vertexLocations
# used to initially create edges
def getEdgeLocations(self, hex):
edgeLocations = []
x = hex.X
y = hex.Y
offset = x % 2
offset = 0-offset
edgeLocations.append((2*x,2*y+offset))
edgeLocations.append((2*x,2*y+1+offset))
edgeLocations.append((2*x+1,2*y+offset))
edgeLocations.append((2*x+1,2*y+2+offset))
edgeLocations.append((2*x+2,2*y+offset))
edgeLocations.append((2*x+2,2*y+1+offset))
return edgeLocations
def getVertices(self, hex):
hexVertices = []
x = hex.X
y = hex.Y
offset = x % 2
offset = 0-offset
hexVertices.append(self.vertices[x][2*y+offset]) # top vertex
hexVertices.append(self.vertices[x][2*y+1+offset]) # left top vertex
hexVertices.append(self.vertices[x][2*y+2+offset]) # left bottom vertex
hexVertices.append(self.vertices[x+1][2*y+offset]) # right top vertex
hexVertices.append(self.vertices[x+1][2*y+1+offset]) # right bottom vertex
hexVertices.append(self.vertices[x+1][2*y+2+offset]) # bottom vertex
return hexVertices
def getEdges(self, hex):
hexEdges = []
x = hex.X
y = hex.Y
offset = x % 2
offset = 0-offset
hexEdges.append(self.edges[2*x][2*y+offset])
hexEdges.append(self.edges[2*x][2*y+1+offset])
hexEdges.append(self.edges[2*x+1][2*y+offset])
hexEdges.append(self.edges[2*x+1][2*y+2+offset])
hexEdges.append(self.edges[2*x+2][2*y+offset])
hexEdges.append(self.edges[2*x+2][2*y+1+offset])
return hexEdges
# returns (start, end) tuple
def getVertexEnds(self, edge):
x = edge.X
y = edge.Y
vertexOne = self.vertices[(x-1)/2][y]
vertexTwo = self.vertices[(x+1)/2][y]
if x%2 == 0:
vertexOne = self.vertices[x/2][y]
vertexTwo = self.vertices[x/2][y+1]
return (vertexOne, vertexTwo)
def getEdgesOfVertex(self, vertex):
vertexEdges = []
x = vertex.X
y = vertex.Y
offset = -1
if x % 2 == y % 2: offset = 1
edgeOne = self.edges[x*2][y-1]
edgeTwo = self.edges[x*2][y]
edgeThree = self.edges[x*2+offset][y]
if edgeOne != None: vertexEdges.append(edgeOne)
if edgeTwo != None: vertexEdges.append(edgeTwo)
if edgeThree != None: vertexEdges.append(edgeThree)
return vertexEdges
def getHexes(self, vertex):
vertexHexes = []
x = vertex.X
y = vertex.Y
xOffset = x % 2
yOffset = y % 2
if x < len(self.hexagons) and y/2 < len(self.hexagons[x]):
hexOne = self.hexagons[x][y/2]
if hexOne != None: vertexHexes.append(hexOne)
weirdX = x
if (xOffset+yOffset) == 1: weirdX = x-1
weirdY = y/2
if yOffset == 1: weirdY += 1
else: weirdY -= 1
if weirdX >= 0 and weirdX < len(self.hexagons) and weirdY >= 0 and weirdY < len(self.hexagons):
hexTwo = self.hexagons[weirdX][weirdY]
if hexTwo != None: vertexHexes.append(hexTwo)
if x > 0 and x < len(self.hexagons) and y/2 < len(self.hexagons[x]):
hexThree = self.hexagons[x-1][y/2]
if hexThree != None: vertexHexes.append(hexThree)
return vertexHexes
謝謝:)該頁面不包括邊緣和頂點,但是我在http://www-cs-students.stanford.edu/~amitp/game-programming/上的網格部分的關係之間的關係中介紹了它們。網格/(這些圖表用於方形網格,但表格也包括軸向六角網格的公式) – amitp 2013-06-07 00:58:12