You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

新手求助:如何在Godot中使用A*实现玩家寻路功能?

Godot中基于TileMap实现A*寻路的实操步骤

作为Godot新手,不用从零手动实现A*算法,Godot自带的AStar2D节点已经封装好了高效的寻路逻辑,结合你的TileMap场景,按以下步骤操作即可:

一、确认可通行瓦片标识

从你提供的is_tile_vacant代码来看,你将瓦片ID为0的标记为可通行,请先确认这个逻辑和你TileMap编辑器中的配置一致(即可通行瓦片的ID确实是0)。

二、添加并初始化AStar2D节点

  1. 在TileMap所在场景中添加一个AStar2D节点(命名为AStar即可)。
  2. 编写初始化函数,遍历TileMap所有瓦片,将可通行位置注册到AStar2D中:
func _ready():
    init_astar()
    # 初始化玩家位置
    $Player.position = get_player_init_pos()

func init_astar():
    var astar = $AStar
    astar.clear()
    
    # 获取TileMap的实际使用范围(自动适配地图大小)
    var used_rect = get_used_rect()
    for x in range(used_rect.position.x, used_rect.end.x):
        for y in range(used_rect.position.y, used_rect.end.y):
            var tile_pos = Vector2i(x, y)
            # 仅添加可通行瓦片(ID为0)作为寻路节点
            if get_cellv(tile_pos) == 0:
                # 转换为世界坐标并居中(和你的玩家初始位置逻辑对齐)
                var world_pos = map_to_world(tile_pos) + half_cell_size
                astar.add_point(tile_pos, world_pos)
                
                # 连接上下左右四个相邻的可通行节点,代价设为1
                var neighbors = [Vector2i(1,0), Vector2i(-1,0), Vector2i(0,1), Vector2i(0,-1)]
                for dir in neighbors:
                    var neighbor_pos = tile_pos + dir
                    if get_cellv(neighbor_pos) == 0:
                        astar.connect_points(tile_pos, neighbor_pos, false)

三、获取玩家到目标的路径

当需要触发移动(比如鼠标点击地图)时,执行以下逻辑获取路径:

func get_move_path(target_world_pos):
    var astar = $AStar
    var start_tile = world_to_map($Player.position)
    var target_tile = world_to_map(target_world_pos)
    
    # 检查起点和终点是否都在可通行节点中
    if astar.has_point(start_tile) && astar.has_point(target_tile):
        # 获取平滑路径(第三个参数true表示路径点居中)
        return astar.get_path($Player.position, map_to_world(target_tile) + half_cell_size, true)
    else:
        return [] # 路径不可达时返回空数组

四、让玩家沿路径平滑移动

拿到路径后,用Tween实现平滑移动:

func move_player(path):
    if path.size() == 0:
        return
    
    var tween = create_tween()
    tween.set_ease(Tween.EASE_IN_OUT)
    tween.set_trans(Tween.TRANS_LINEAR)
    
    # 逐个路径点移动
    for i in range(path.size() - 1):
        tween.tween_property($Player, "position", path[i+1], 0.2)

五、优化现有代码

你的is_tile_vacant函数可以替换为AStar的节点检测逻辑,无需单独做单次障碍物判断;get_player_init_pos可以直接用来初始化玩家位置,确保和寻路节点的坐标规则一致。


内容的提问来源于stack exchange,提问作者Marco Mulgado

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 06:01:00