Exemplo n.º 1
0
        /// <summary> 搜索下一个坐标点 </summary>
        private static void SearchPoint(AStarPoint curPoint, AStarPoint nextPoint)
        {
            // 不可到达或在 CloseList 中则返回
            if (!nextPoint.IsReachable || CloseList.Contains(nextPoint))
            {
                return;
            }

            // next 不在 OpenList 中
            if (!OpenList.Contains(nextPoint))
            {
                // 将 next 加入 OpenList
                OpenList.AddLast(nextPoint);
                // 设置 next 的父节点
                nextPoint.Parent = curPoint;
                // 计算 next 的 G 值
                nextPoint.G = curPoint.G + 1;
            }
            // next 在 OpenList 中,且新的 G 值更小
            else if (curPoint.G + 1 < nextPoint.G)
            {
                // 设置 next 的父节点
                nextPoint.Parent = curPoint;
                // 计算 next 的 G 值
                nextPoint.G = curPoint.G + 1;
            }
        }
Exemplo n.º 2
0
        public static IEnumerable <Vector2Int> GetPath(Block[][] blocks, Vector2Int start, Vector2Int end)
        {
            // 判断目标坐标是否可到达,不可到达则直接返回
            Block block = blocks[end.x][end.y];

            if (!block.Reachable)
            {
                return(null);
            }

            // 根据 blocks 构造 points
            AStarPoint[][] points = new AStarPoint[blocks.Length][];
            for (int i = 0; i < points.Length; i++)
            {
                points[i] = new AStarPoint[blocks[i].Length];
                for (int j = 0; j < points[i].Length; j++)
                {
                    points[i][j] = new AStarPoint(blocks[i][j].Coords, blocks[i][j].Reachable, end);
                }
            }

            bool pathIsFound = false; // 路径标识

            OpenList  = new LinkedList <AStarPoint>();
            CloseList = new LinkedList <AStarPoint>();
            // 将起始点加入 OpenList
            OpenList.AddLast(points[start.x][start.y]);
            // 循环条件:OpenList 不为空且还未找到路径
            while (OpenList.Count != 0 && !pathIsFound)
            {
                // 找到 F 值最小的 point
                AStarPoint point = null;
                foreach (var item in OpenList)
                {
                    if (point == null || point.F >= item.F)
                    {
                        point = item;
                    }
                }
                // 将 point 移出 OpenList,加入 CloseList
                OpenList.Remove(point);
                CloseList.AddLast(point);
                // 依次搜索周围四个点
                foreach (var delta in OFFSET_COORDS)
                {
                    Vector2Int nextCoords = point.Coords + delta;
                    // 坐标不合法则返回
                    if (!MapUIUtil.IsBlockReachable(blocks, nextCoords))
                    {
                        continue;
                    }
                    // 搜索 next
                    AStarPoint nextPoint = points[nextCoords.x][nextCoords.y];
                    SearchPoint(point, nextPoint);
                    // 搜索点为 end 说明找到路径了,直接跳出循环
                    if (nextPoint.Coords == end)
                    {
                        pathIsFound = true;
                        break;
                    }
                }
            }

            // 未找到路径则返回 null
            if (!pathIsFound)
            {
                return(null);
            }
            // 找到路径则从 end 开始依次读取父节点并加入 path,最后返回 path
            LinkedList <Vector2Int> path = new LinkedList <Vector2Int>();
            AStarPoint wayPoint          = points[end.x][end.y];

            while (wayPoint != null)
            {
                path.AddFirst(wayPoint.Coords);
                wayPoint = wayPoint.Parent;
            }
            return(path);
        }