Development in progress!
API might change without further notice until first major release 1.x.x.
HexGrid
库提供了一种简单直观的方式来处理六边形网格。它在后台处理所有的数学计算,因此您可以专注于更重要的事情。
该库旨在用于通用的后端。 因此,它不执行任何 UI 或渲染。 但是,它提供了渲染所需的计算。
n
步内查找可到达的六边形 (广度优先搜索)。ShadowCasting
)。HexGrid 演示应用程序,使用 SpriteKit。(也可在 App Store 中获得。) HexGrid 演示应用程序,使用 SwiftUI。
将 HexGrid 作为依赖项添加到您的 Package.swift
文件中。
import PackageDescription
let package = Package(
name: "MyApp",
dependencies: [
...
// Add HexGrid package here
.package(url: "https://github.com/fananek/hex-grid.git", from: "0.4.11")
],
...
targets: [
.target(name: "App", dependencies: [
.product(name: "HexGrid", package: "hex-grid"),
...
将 HexGrid 包导入到您的代码中。
import HexGrid
...
// your code goes here
可以使用一组单元格坐标初始化网格,或者 HexGrid 可以为您生成一些标准形状的网格。
例如
...
// create grid of hexagonal shape
var grid = HexGrid(shape: GridShape.hexagon(10))
// or rectangular shape
var grid = HexGrid(shape: GridShape.rectangle(8, 12))
// or triangular shape
var grid = HexGrid(shape: GridShape.triangle(6))
有关更多详细信息以及可用网格形状的完整列表,请参阅下面的 GridShape
部分。
示例
...
// create new HexGrid
let gridCells: Set<Cell> = try [
Cell(CubeCoordinates(x: 2, y: -2, z: 0)),
Cell(CubeCoordinates(x: 0, y: -1, z: 1)),
Cell(CubeCoordinates(x: -1, y: 1, z: 0)),
Cell(CubeCoordinates(x: 0, y: 2, z: -2))
]
var grid = HexGrid(cells: gridCells)
...
请注意,假设您要绘制网格,您需要考虑是为每个单元格 (hexSize
) 传递大小还是为整个网格 (pixelSize
) 传递大小到初始化器。(参见下面的“绘制网格”。)
HexGrid 符合 swift Codable
协议,因此可以轻松地编码为 JSON 或从 JSON 解码。
示例
// encode (grid to JSON)
let grid = HexGrid(shape: GridShape.hexagon(5) )
let encoder = JSONEncoder()
let data = try encoder.encode(grid)
// decode (JSON to grid)
let decoder = JSONDecoder()
let grid = try decoder.decode(HexGrid.self, from: data)
几乎所有函数都有两个变体。 一个使用 Cell
,另一个使用 CubeCoordinates
。 使用那些更好地满足您需求的。
let cell = grid.cellAt(try CubeCoordinates(x: 1, y: 0, z: -1))
检查坐标是否有效(意味着它在网格的 cells
数组中具有相应的 Cell
)。
// returns Bool
isValidCoordinates(try CubeCoordinates(x: 2, y: 4, z: -6))
let blockedCells = grid.blockedCells()
// or
let nonBlockedCells = grid.nonBlockedCells()
// get neighbor for a specific Cell
let neighbor = try grid.neighbor(
for: someCell,
at: Direction.Pointy.northEast.rawValue)
// get just neighbor coordinates
let neighborCoordinates = try grid.neighborCoordinates(
for: someCoordinates,
at: Direction.Pointy.northEast.rawValue)
// get all neighbors for a specific Cell
let neighbors = try grid.neighbors(for: someCell)
// get only coordinates of all neighbors
let neighborsCoords = try grid.neighbors(for: someCoordinates)
// returns nil in case line doesn't exist
let line = try grid.line(from: originCell, to: targetCell)
// returns all cells making a ring from origin cell in radius
let ring = try grid.ring(from: originCell, in: 2)
// returns all cells making a filled ring from origin cell in radius
let ring = try grid.filledRing(from: originCell, in: 2)
// find all reachable cells (max. 4 steps away from origin)
let reachableCells = try grid.findReachable(from: origin, in: 4)
// returns nil in case path doesn't exist at all
let path = try grid.findPath(from: originCell, to: targetCell)
Cell
具有一个名为 isOpaque
的属性。 它的值可以是 true
或 false
。 基于此信息,可以计算所谓的 视场。 这意味着从网格上的特定位置可见的所有单元格,同时考虑到所有不透明的障碍物。
// set cell as opaque
obstacleCell.isOpaque = true
为了获得视场,只需调用以下函数。
// find all hexes visible in radius 4 from origin cell
let visibleHexes = try grid.fieldOfView(from: originCell, in: 4)
默认情况下,一旦从原点单元格可以看到单元格的中心,该单元格就被认为是可见的。 如果您还想包括部分可见的单元格,请使用可选参数 includePartiallyVisible
。
// find all hexes even partially visible in radius 4 from origin cell
let visibleHexesIncludingPartials = try grid.fieldOfView(from: originCell, in: 4, includePartiallyVisible: true)
在内部,HexGrid
使用以下两种方法之一计算所有“像素坐标”
Cell
的大小(存储在 hexSize
属性中)。...或者...
pixelSize
属性中)。请注意,
hexSize
和pixelSize
属性在内部都存储为HexSize
结构。 尽量不要对此感到困惑!HexSize
只是存储width
和height
值的便捷方式。
您要使用的 HexGrid
初始化器的类型将取决于哪种方法最适合您的用例。 指定 hexSize
时,会自动为您计算 pixelSize
;指定 pixelSize
时,也会自动设置 hexSize
。
虽然无法直接修改 hexSize
或 pixelSize
属性(初始化后),但您可以随时使用 fitGrid(in size: HexSize)
函数设置网格的 pixelSize
(并从中重新计算 hexSize
)。 请注意,这也会重置 origin
属性。
您可以将 HexGrid
的 origin
属性视为 CubeCoordinate
0,0,0
处 Cell
的中心点。
请注意,您可以在初始化时指定
origin
,但仅在使用cellSize
方法时。 指定pixelSize
时,会自动为您设置原点,以便网格“适合”指定的宽度和高度。
如果您想更改网格的像素坐标,更改 origin
属性非常重要。 更改 origin
将修改所有像素计算函数的返回值。 您可以使用它来为网格应用偏移量,或稍后“重新居中”它。
通常,在绘制六边形时,您需要每个 Cell
的多边形角的屏幕坐标。
let corners = grid.polygonCorners(for: someCell)
此函数返回 Cell
中心的 Point
结构(x: 和 y: 值)。
let screenCoords = grid.pixelCoordinates(for: someCell)
// return cell for specified screen coordinates (or nil if such cell doesn't exists)
let cell = try grid.cellAt(point)
有关详细信息,请参见完整的 文档
表示网格本身,也是 HexGrid 库的入口点。
HexGrid
由一组 Cells
和其他一些属性定义。 它们共同构成网格设置。 换句话说,它将网格单元格放入有意义的上下文中。 因此,大多数可用操作都是直接在网格实例上调用的,因为它只有在这种上下文中(网格设置)才有意义。
属性
Set<Cell>
- 网格单元Orientation
- 参见 Orientation 枚举OffsetLayout
- 参见 OffsetLayout 枚举HexSize
- 六边形的宽度和高度Point
- 网格原点的“显示坐标”(x,y)HexSize
- 整个网格的像素宽度和高度[String: Attribute]
- 自定义属性的字典(支持大多数原始类型以及嵌套)Cell 是网格的构建块。
属性
CubeCoordinates
- 单元格在网格坐标系上的位置[String: Attribute]
- 自定义属性的字典(支持大多数原始类型以及嵌套)Bool
- 由算法使用(reachableCells,pathfinding 等)Bool
- 由 fieldOfView 算法使用Float
- 由寻路算法使用。 为了简单起见,让我们把图论放在一边。 您可以将成本想象为通过单元格所需的能量量。 然后,寻路算法搜索需要较少努力的路径。HexGrid 库中最常用的坐标是立方体坐标系。 这种类型的坐标具有三个轴 x,y 和 z。 唯一的条件是其所有值的总和必须等于零。
// valid cube coordinates
CubeCoordinates(x: 1, y: 0, z: -1) -> sum = 0
// invalid cube coordinates
CubeCoordinates(x: 1, y: 1, z: -1) -> sum = 1 -> throws error
有关更多详细信息,请查看 Amit Patel 的解释。
选项
pointyOnTop
- ⬢flatOnTop
- ⬣OffsetLayout 主要用于矩形形状的网格。 它有两个选项,但它们的含义可能因网格方向而异。
选项
odd
even
根据六边形的方向,有四种偏移类型。 “row”类型与尖顶六边形一起使用,“column”类型与平顶六边形一起使用。
可以将此枚举中的案例传递到 HexGrid
构造函数中,以生成各种形状和大小的网格。
选项
rectangle(Int, Int)
- 关联的值是生成的网格的列宽和行高。 网格的侧面基本上将平行于屏幕的边缘。parallelogram(Int, Int)
- 关联的值都是边长。hexagon(Int)
- 这会生成一个规则的六边形形状的网格,所有边的长度都与关联的值相同。elongatedHexagon(Int, Int)
- 这用于生成一个形状像规则六边形的网格,该网格在一个维度上被拉伸或拉长。 关联的值是边长。irregularHexagon(Int, Int)
- 这用于生成一个形状像六边形的网格,其中每隔一条边的长度是两个关联的值。triangle(Int)
- 生成一个等边三角形,所有边的长度都与关联的值相同。选项
left
right
Direction 枚举是一致且人类可识别的方向命名。 使用 direction 枚举不仅更加方便,而且还有助于避免错误。 最好只是说 _“嘿,我在单元格 X 上,想去北方。”_ 而不是想 _“北方方向的索引到底是什么?”_,不是吗?
选项
Direction.Flat
north
northEast
southEast
south
southWest
northWest
Direction.Pointy
northEast
east
southEast
southWest
west
northWest
实际上,每个网格方向都有一组单独的方向。 这是因为两个原因。 首先,某些方向仅对一种或另一种方向有效。 其次,方向原始值会根据方向而移动。
另请参阅参与该项目的 贡献者 列表。
HexGrid 包中包含的所有代码均受 MIT 许可协议约束。