AStarGrid2D
继承: RefCounted < Object
A* 的一种实现,用于寻找疏松 2D 网格中两点之间的最短路径。
描述
AStarGrid2D 是 AStar2D 的变种,针对疏松 2D 网格进行了优化。因为不需要手动创建点并进行连接,所以用起来更加简单。这个类还支持使用不同的启发方法、斜向移动模式、跳跃模式,从而加速运算。
要使用 AStarGrid2D,你只需要设置网格的 region,cell_size 可以不设置,最后调用 update() 方法即可:
var astar_grid = AStarGrid2D.new()
astar_grid.region = Rect2i(0, 0, 32, 32)
astar_grid.cell_size = Vector2(16, 16)
astar_grid.update()
print(astar_grid.get_id_path(Vector2i(0, 0), Vector2i(3, 4))) # 输出 [(0, 0), (1, 1), (2, 2), (3, 3), (3, 4)]
print(astar_grid.get_point_path(Vector2i(0, 0), Vector2i(3, 4))) # 输出 [(0, 0), (16, 16), (32, 32), (48, 48), (48, 64)]
AStarGrid2D astarGrid = new AStarGrid2D();
astarGrid.Region = new Rect2I(0, 0, 32, 32);
astarGrid.CellSize = new Vector2I(16, 16);
astarGrid.Update();
GD.Print(astarGrid.GetIdPath(Vector2I.Zero, new Vector2I(3, 4))); // 输出 [(0, 0), (1, 1), (2, 2), (3, 3), (3, 4)]
GD.Print(astarGrid.GetPointPath(Vector2I.Zero, new Vector2I(3, 4))); // 输出 [(0, 0), (16, 16), (32, 32), (48, 48), (48, 64)]
要从寻路网格中移除某个点,必须使用 set_point_solid() 将其设置为“实心”。
教程
属性
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
方法
_compute_cost(from_id: Vector2i, to_id: Vector2i) virtual const |
|
_estimate_cost(from_id: Vector2i, end_id: Vector2i) virtual const |
|
void |
clear() |
void |
fill_solid_region(region: Rect2i, solid: bool = true) |
void |
fill_weight_scale_region(region: Rect2i, weight_scale: float) |
get_id_path(from_id: Vector2i, to_id: Vector2i, allow_partial_path: bool = false) |
|
get_point_data_in_region(region: Rect2i) const |
|
get_point_path(from_id: Vector2i, to_id: Vector2i, allow_partial_path: bool = false) |
|
get_point_position(id: Vector2i) const |
|
get_point_weight_scale(id: Vector2i) const |
|
is_dirty() const |
|
is_in_bounds(x: int, y: int) const |
|
is_in_boundsv(id: Vector2i) const |
|
is_point_solid(id: Vector2i) const |
|
void |
set_point_solid(id: Vector2i, solid: bool = true) |
void |
set_point_weight_scale(id: Vector2i, weight_scale: float) |
void |
update() |
枚举
enum Heuristic: 🔗
Heuristic HEURISTIC_EUCLIDEAN = 0
欧几里德启发式算法将被用于寻路,使用的公式如下:
dx = abs(to_id.x - from_id.x)
dy = abs(to_id.y - from_id.y)
result = sqrt(dx * dx + dy * dy)
注意:这也是 AStar3D 和 AStar2D 默认使用的内部启发式算法(包括可能的 z 轴坐标)。
Heuristic HEURISTIC_MANHATTAN = 1
曼哈顿启发式算法将被用于寻路,使用的公式如下:
dx = abs(to_id.x - from_id.x)
dy = abs(to_id.y - from_id.y)
result = dx + dy
注意:该启发式算法旨在与 4 边正交运动一起使用,4 边正交运动可通过将 diagonal_mode 设置为 DIAGONAL_MODE_NEVER 来提供。
Heuristic HEURISTIC_OCTILE = 2
Octile 启发式算法将被用于寻路,使用的公式如下:
dx = abs(to_id.x - from_id.x)
dy = abs(to_id.y - from_id.y)
f = sqrt(2) - 1
result = (dx < dy) ? f * dx + dy : f * dy + dx;
Heuristic HEURISTIC_CHEBYSHEV = 3
切比雪夫启发式算法将被用于寻路,使用的公式如下:
dx = abs(to_id.x - from_id.x)
dy = abs(to_id.y - from_id.y)
result = max(dx, dy)
Heuristic HEURISTIC_MAX = 4
代表 Heuristic 枚举的大小。
enum DiagonalMode: 🔗
DiagonalMode DIAGONAL_MODE_ALWAYS = 0
该寻路算法将忽略目标单元格周围的实体邻居,并允许沿对角线通过。
DiagonalMode DIAGONAL_MODE_NEVER = 1
该寻路算法将忽略所有对角线,并且路径始终是正交的。
DiagonalMode DIAGONAL_MODE_AT_LEAST_ONE_WALKABLE = 2
如果在特定路径段的相邻单元格周围放置了至少两个障碍物,则该寻路算法将避免使用对角线。
DiagonalMode DIAGONAL_MODE_ONLY_IF_NO_OBSTACLES = 3
如果在特定路径段的相邻单元格周围放置了任意障碍物,则该寻路算法将避免使用对角线。
DiagonalMode DIAGONAL_MODE_MAX = 4
代表 DiagonalMode 枚举的大小。
enum CellShape: 🔗
CellShape CELL_SHAPE_SQUARE = 0
矩形单元格形状。
CellShape CELL_SHAPE_ISOMETRIC_RIGHT = 1
菱形单元格形状(用于等轴外观)。单元格坐标布局,其中水平轴朝向右上方,垂直轴朝向右下方。
CellShape CELL_SHAPE_ISOMETRIC_DOWN = 2
菱形单元格形状(用于等轴外观)。单元格坐标布局,其中水平轴朝向右下方,垂直轴朝向左下方。
CellShape CELL_SHAPE_MAX = 3
代表 CellShape 枚举的大小。
属性说明
单元格形状。影响位置在栅格中的放置方式。如果发生变化,需要在查找下一条路径之前调用 update()。
Vector2 cell_size = Vector2(1, 1) 🔗
要用于计算由 get_point_path() 返回的结果点位置的点单元的大小。如果更改了这个值,在查找下一个路径之前需要调用 update()。
Heuristic default_compute_heuristic = 0 🔗
默认 Heuristic,用于在没有覆盖 _compute_cost() 时计算两点之间的消耗。
Heuristic default_estimate_heuristic = 0 🔗
默认 Heuristic,用于在没有覆盖 _estimate_cost() 时计算该点和终点之间的消耗。
DiagonalMode diagonal_mode = 0 🔗
void set_diagonal_mode(value: DiagonalMode)
DiagonalMode get_diagonal_mode()
特定的 DiagonalMode,会强制路径避免或接受特定的对角线。
bool jumping_enabled = false 🔗
启用或禁用跳跃,以跳过中间点并加快搜索算法的速度。
注意:目前,打开它会在寻路过程中忽略权重缩放。
Vector2 offset = Vector2(0, 0) 🔗
栅格的偏移量,将被应用以计算 get_point_path() 返回的结果点的位置。如果发生变化,需要在查找下一条路径之前调用 update()。
Rect2i region = Rect2i(0, 0, 0, 0) 🔗
栅格上用来寻路的区域。如果发生变化,需要在查找下一条路径之前调用 update()。
Vector2i size = Vector2i(0, 0) 🔗
已弃用: Use region instead.
栅格的大小(每个轴上大小为 cell_size 的单元格数)。如果发生变化,需要在查找下一条路径之前调用 update()。
方法说明
float _compute_cost(from_id: Vector2i, to_id: Vector2i) virtual const 🔗
计算两个连接点之间的成本时调用。
请注意,这个函数在默认的 AStarGrid2D 类中是隐藏的。
float _estimate_cost(from_id: Vector2i, end_id: Vector2i) virtual const 🔗
估算某个点和路径终点之间的成本时调用。
请注意,这个函数在默认的 AStarGrid2D 类中是隐藏的。
void clear() 🔗
清空网格并将 region 设置为 Rect2i(0, 0, 0, 0)。
void fill_solid_region(region: Rect2i, solid: bool = true) 🔗
使用指定的值填充网格上 region 区域的实心标志。
注意:调用该函数后不需要调用 update()。
void fill_weight_scale_region(region: Rect2i, weight_scale: float) 🔗
使用指定的值填充网格上 region 区域的权重缩放。
注意:调用该函数后不需要调用 update()。
Array[Vector2i] get_id_path(from_id: Vector2i, to_id: Vector2i, allow_partial_path: bool = false) 🔗
返回一个数组,其中包含 AStar2D 在给定点之间找到的路径中的点。数组从路径的起点到终点进行排序。
如果 from_id 点被禁用,则返回一个空数组(即使 from_id == to_id)。
如果 from_id 点未被禁用,没有通往目标的有效路径并且 allow_partial_path 为 true,则会返回通往距离目标最近的可达点的路径。
注意:如果 allow_partial_path 为 true 并且 to_id 处于禁用状态,搜索耗时可能异常地大。
Array[Dictionary] get_point_data_in_region(region: Rect2i) const 🔗
返回 region 范围内点数据(id: Vector2i, position: Vector2, solid: bool, weight_scale: float)的字典数组。
PackedVector2Array get_point_path(from_id: Vector2i, to_id: Vector2i, allow_partial_path: bool = false) 🔗
返回一个数组,其中包含 AStarGrid2D 在给定点之间找到的路径上的点。数组从路径的起点到终点排序。
如果 from_id 点被禁用,则返回一个空数组(即使 from_id == to_id)。
如果 from_id 点未被禁用,没有通往目标的有效路径并且 allow_partial_path 为 true,则会返回通往距离目标最近的可达点的路径。
注意:该方法不是线程安全的,同一时间只能有一个 Thread 使用。请考虑使用 Mutex 来确保线程独占访问,避免竞态条件。
另外,如果 allow_partial_path 为 true 并且 to_id 处于禁用状态,搜索耗时可能异常地大。
Vector2 get_point_position(id: Vector2i) const 🔗
返回与给定 id 相关联的点的位置。
float get_point_weight_scale(id: Vector2i) const 🔗
返回与给定 id 关联的点的权重比例。
表示网格参数发生改变,需要调用 update()。
bool is_in_bounds(x: int, y: int) const 🔗
如果 x 和 y 是有效的网格坐标(ID),即如果它位于 region 内部,则返回 true。相当于 region.has_point(Vector2i(x, y))。
bool is_in_boundsv(id: Vector2i) const 🔗
如果 id 向量是有效的网格坐标,即如果它位于 region 内部,则返回 true。相当于 region.has_point(id)。
bool is_point_solid(id: Vector2i) const 🔗
如果寻路时会禁用某个点,则返回 true。默认情况下,所有点均处于启用状态。
void set_point_solid(id: Vector2i, solid: bool = true) 🔗
禁用或启用指定的寻路点。用于制造障碍物。默认情况下,启用所有点。
注意:调用该函数后不需要调用 update()。
void set_point_weight_scale(id: Vector2i, weight_scale: float) 🔗
为具有给定 id 的点设置 weight_scale。在确定从相邻点到该点穿越路段的总成本时,weight_scale 要乘以 _compute_cost() 的结果。
注意:调用该函数后不需要调用 update()。
void update() 🔗
根据参数更新网格的内部状态,以准备搜索路径。如果更改了 region、cell_size 或 offset 等参数就需要调用它。如果是这种情况,则 is_dirty() 将返回 true,需要调用此方法。
注意:会清空所有点的数据(坚固以及权重比例)。