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

A*寻路算法生成错误路径求助:敌人穿墙追踪玩家

问题描述

我正在开发一款迷宫游戏,当玩家进入敌人的侦测范围后,敌人会通过A*寻路算法对玩家进行追踪。迷宫采用程序化(procedural)方式生成,迷宫中的每个区块都拥有包含x、z坐标的MapLocation,寻路起点为敌人位置,终点为玩家位置。但有时当玩家进入敌人范围后,寻路会无视迷宫的部分墙体直接到达玩家位置。

我已尝试使用曼哈顿距离(Manhattan's Distance)进行启发式计算,但问题并未得到解决。

寻路核心代码
IEnumerator Search(Vector3 start, Vector3 goal)
{
    pathSuccess = false;
    waypoints = new Vector3[0];
    Heap<Path> open = new Heap<Path>(maze.MaxSize);
    HashSet<Path> closed = new HashSet<Path>();

    Path startNode = new Path(maze.GetMapLocation(start), 0, 0, 0, null);
    Path goalNode = new Path(maze.GetMapLocation(goal), 0, 0, 0, null);

    open.Add(startNode);
    lastPos = startNode;

    while (open.Count > 0)
    {
        if (lastPos.Equals(goalNode))
        {
            pathSuccess = true;
            break;
        }
        foreach (MapLocation dir in maze.directions)
        {
            MapLocation neighbour = dir + lastPos.location;
            if (maze.map[neighbour.x, neighbour.z] == 1) continue;
            if (neighbour.x < 1 || neighbour.x >= maze.width || neighbour.z < 1 || neighbour.z >= maze.depth) continue;
            if (IsClosed(neighbour, closed)) continue;

            float G = Vector2.Distance(lastPos.location.ToVector(), neighbour.ToVector()) + lastPos.G;
            float H = Vector2.Distance(neighbour.ToVector(), goalNode.location.ToVector());
            float F = G + H;

            if (!UpdateMarker(neighbour, G, H, F, lastPos, open))
                open.Add(new Path(neighbour, G, H, F, lastPos));
        }
        Path pm = open.RemoveFirst();
        closed.Add(pm);

        lastPos = pm;
    }
    yield return null;
    if (pathSuccess)
    {
        waypoints = RetracePath(startNode);
    }
    PathRequestManager.Instance.FinishedProcessingPath(waypoints, pathSuccess);
}

bool UpdateMarker(MapLocation pos, float g, float h, float f, Path prt, Heap<Path> open)
{
    foreach (Path p in open)
    {
        if (p.location.Equals(pos))
        {
            p.G = g;
            p.H = h;
            p.F = f;
            p.parent = prt;
            return true;
        }
    }
    return false;
}

bool IsClosed(MapLocation marker, HashSet<Path> closed)
{
    foreach (Path p in closed)
    {
        if (p.location.Equals(marker)) return true;
    }
    return false;
}

Vector3[] RetracePath(Path startNode)
{
    Path begin = lastPos;
    List<Vector3> path = new List<Vector3>();
    while (!startNode.Equals(begin) && begin != null)
    {
        path.Add(begin.Position(maze));
        begin = begin.parent;
    }
    path.Reverse();
    return path.ToArray();
}

public MapLocation GetMapLocation(Vector3 position)
{
    MapLocation mapLocation = new MapLocation((int)position.x / scale, (int)position.z / scale);
    return mapLocation;
}
public List<MapLocation> directions = new List<MapLocation>() {
                                        new MapLocation(1,0),
                                        new MapLocation(0,1),
                                        new MapLocation(-1,0),
                                        new MapLocation(0,-1) };
迷宫生成代码
public class Recursive : Maze
{
    public override void Generate()
    {
        Generate(5, 5);
    }

    void Generate(int x, int z)
    {
        if (CountSquareNeighbours(x, z) >= 2) return;
        map[x, z] = 0;

        directions.Shuffle();

        Generate(x + directions[0].x, z + directions[0].z);
        Generate(x + directions[1].x, z + directions[1].z);
        Generate(x + directions[2].x, z + directions[2].z);
        Generate(x + directions[3].x, z + directions[3].z);
    }

}

public byte[,] map;
public virtual void Generate()
{
    for (int z = 0; z < depth; z++)
        for (int x = 0; x < width; x++)
        {
           if(Random.Range(0,100) < 50)
             map[x, z] = 0;     //1 = 墙体  0 = 通道
        }
}
尝试过的曼哈顿距离代码
float H = Mathf.Abs(neighbour.x - goalNode.location.x) + Mathf.Abs(neighbour.z - goalNode.location.z); 

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 18:55:39