C# 像素距离,但你想分配任意值,你可以调整成本。我不知道你是如何得到邻居的。向上是X,Y-1,向下是X,Y+1,左上是X-1,Y-1,等等?此外,你的问题是你希望角色“[走]成对角线”,但你的代码注释是“一个不允许对角线移动的正方形网格”。你能上传一张你期望的

C# 像素距离,但你想分配任意值,你可以调整成本。我不知道你是如何得到邻居的。向上是X,Y-1,向下是X,Y+1,左上是X-1,Y-1,等等?此外,你的问题是你希望角色“[走]成对角线”,但你的代码注释是“一个不允许对角线移动的正方形网格”。你能上传一张你期望的,c#,C#,像素距离,但你想分配任意值,你可以调整成本。我不知道你是如何得到邻居的。向上是X,Y-1,向下是X,Y+1,左上是X-1,Y-1,等等?此外,你的问题是你希望角色“[走]成对角线”,但你的代码注释是“一个不允许对角线移动的正方形网格”。你能上传一张你期望的和看到的图片吗?抱歉,这些注释很旧,我以前在很多不同的游戏中使用过相同的代码。瓷砖是等距布置的,因此直接向上始终是x,y-2 public List<Point> Pathfind(Point start, Point end)


像素距离,但你想分配任意值,你可以调整成本。我不知道你是如何得到邻居的。向上是
X,Y-1
,向下是
X,Y+1
,左上是
X-1,Y-1
,等等?此外,你的问题是你希望角色“[走]成对角线”,但你的代码注释是“一个不允许对角线移动的正方形网格”。你能上传一张你期望的和看到的图片吗?抱歉,这些注释很旧,我以前在很多不同的游戏中使用过相同的代码。瓷砖是等距布置的,因此直接向上始终是x,y-2
 public List<Point> Pathfind(Point start, Point end)
    {
        // nodes that have already been analyzed and have a path from the start to them
        var closedSet = new List<Point>();
        // nodes that have been identified as a neighbor of an analyzed node, but have
        // yet to be fully analyzed
        var openSet = new List<Point> { start };
        // a dictionary identifying the optimal origin point to each node. this is used
        // to back-track from the end to find the optimal path
        var cameFrom = new Dictionary<Point, Point>();
        // a dictionary indicating how far each analyzed node is from the start
        var currentDistance = new Dictionary<Point, int>();
        // a dictionary indicating how far it is expected to reach the end, if the path
        // travels through the specified node.
        var predictedDistance = new Dictionary<Point, float>();
        // initialize the start node as having a distance of 0, and an estmated distance
        // of y-distance + x-distance, which is the optimal path in a square grid that
        // doesn't allow for diagonal movement
        currentDistance.Add(start, 0);
        predictedDistance.Add(
        start,
        0 + +Math.Abs(start.X - end.X) + Math.Abs(start.Y - end.Y)
        );

        // if there are any unanalyzed nodes, process them
        while (openSet.Count > 0)
        {
            // get the node with the lowest estimated cost to finish
            var current = (from p in openSet orderby predictedDistance[p] ascending select p).First();
            // if it is the finish, return the path
            if (current.X == end.X && current.Y == end.Y)
            {
                // generate the found path
                return ReconstructPath(cameFrom, end);
            }
            // move current node from open to closed
            openSet.Remove(current);
            closedSet.Add(current);
            // process each valid node around the current node
            foreach (var neighbor in GetNeighborNodes(current))
            {
                var tempCurrentDistance = currentDistance[current] + 1;
                // if we already know a faster way to this neighbor, use that route and
                // ignore this one
                if (closedSet.Contains(neighbor) && tempCurrentDistance >= currentDistance[neighbor])
                {
                    continue;
                }
                // NOT PASSABLE
                if (Globals.mapArray[neighbor.X,neighbor.Y].Passable == false)
                {
                    continue;
                }
                // if we don't know a route to this neighbor, or if this is faster,
                // store this route
                if (!closedSet.Contains(neighbor)|| tempCurrentDistance < currentDistance[neighbor])
                {
                    if (cameFrom.Keys.Contains(neighbor))
                    {
                        cameFrom[neighbor] = current;
                    }
                    else
                    {
                        cameFrom.Add(neighbor, current);
                    }

                    currentDistance[neighbor] = tempCurrentDistance + 10;
                    predictedDistance[neighbor] = currentDistance[neighbor] + Math.Abs(neighbor.X - end.X) + Math.Abs(neighbor.Y - end.Y);
                    predictedDistance[neighbor] = predictedDistance[neighbor] * 10;

                    // if this is a new node, add it to processing
                    if (!openSet.Contains(neighbor))
                    {
                        openSet.Add(neighbor);
                    }
                }
            }
        }
        // unable to figure out a path, abort.
        List<Point> noPath = new List<Point>();
        Point n = new Point();
        n.X = -1; n.Y = -1;
        noPath.Add(n);
        return noPath;
    }

private IEnumerable<Point> GetNeighborNodes(Point node)
    {
        var nodes = new List<Point>();
        if (node.X > 0 && node.Y > 0 && node.X < Globals.xSize - 1 && node.Y < Globals.ySize - 1)
        {
            // up
            nodes.Add(new Point(node.X, node.Y - 2));             
            // right
            nodes.Add(new Point(node.X + 1, node.Y));
            // down
            nodes.Add(new Point(node.X, node.Y + 2));
            // left
            nodes.Add(new Point(node.X - 1, node.Y));

            // DIAGONAL
            if (node.Y % 2 == 0)
            {
                // UP LEFT
                nodes.Add(new Point(node.X, node.Y - 1));                
                // UP RIGHT
                nodes.Add(new Point(node.X - 1, node.Y - 1));
                // DOWN LEFT
                nodes.Add(new Point(node.X-1, node.Y + 1));
                // DOWN RIGHT
                nodes.Add(new Point(node.X, node.Y + 1));
            }
            else
            {
                // UP LEFT
                nodes.Add(new Point(node.X+1, node.Y - 1));
                // UP RIGHT
                nodes.Add(new Point(node.X, node.Y - 1));
                // DOWN LEFT
                nodes.Add(new Point(node.X, node.Y + 1));
                // DOWN RIGHT
                nodes.Add(new Point(node.X+1, node.Y + 1)); 
            }
        }

        return nodes;
    }