c#寻径,平滑移动敌人到玩家.在固体周围走动

本文关键字:周围走 玩家 寻径 平滑 移动 敌人 | 更新日期: 2023-09-27 18:03:19

我需要一种方法去执行寻径到我的游戏中。

例如A*欧几里得可以很好地用于此。

我有一个多维数组我的Tile类有一个矩形用于边界和is_solid变量。玩家不受贴图的限制,可以自由移动。这样敌人就能顺利地找到通往玩家的路。

我曾尝试在web上实现示例,或在同胞Stackoverflow数据库上。但是无济于事,我不能修改它们来配合我的项目。

有任何你认为适合我开发游戏的方法的例子/教程,我可以更容易地将其执行到我的游戏中。

c#寻径,平滑移动敌人到玩家.在固体周围走动

我是在这篇很棒的文章的帮助下这样做的:

public class MyEdge//used edges and notes for my graph
{
    public int To { get; private set; }
    public int From { get; private set; }
    protected MyNode from;
    protected MyNode to;

    public MyEdge(int from, int to, MyGraph g)
    {
        From = from;
        To = to;
        this.from = g.GetNode(from);
        this.to = g.GetNode(to);
    }
    public MyNode NodeFrom()
    {
        return from;
    }
    public MyNode NodeTo()
    {
        return to;
    }
}
public class MyNode
{
    public int Index { get; private set; }
    public Vector2D Pos { get; private set; }
    public List<MyEdge> Edges { get; private set; }
    public MyNode parent = null;
    public double G = double.MaxValue;
    public double H = 0;
    public double F { get { return G + H; } }

    public MyNode(int x, int y)
    {
        Edges = new List<MyEdge>();
        Pos = new Vector2D(x, y);
        Index = -1;
    }
    public MyNode(Vector2D pos)
    {
        Edges = new List<MyEdge>();
        Pos = pos;
        Index = -1;
    }
    public MyNode(int x, int y, int idx)
    {
        Edges = new List<MyEdge>();
        Pos = new Vector2D(x, y);
        Index = idx;
    }
    public MyNode(Vector2D pos, int idx)
    {
        Edges = new List<MyEdge>();
        Pos = pos;
        Index = idx;
    }
}

注:边有节点,节点有边。这是为了更好的性能

public List<MyNode> GetPath(Vector2D startPoint, Vector2D endPoint)
    {
        //create the open list of nodes, initially containing only our starting node
        //create the closed list of nodes, initially empty
        List<MyNode> open = new List<MyNode>();
        List<MyNode> closed = new List<MyNode>();

        //Find the starting node
        MyNode start = FindNearestNode(startPoint);
        if (start == null)
            return null;
        //Find the ending node
        MyNode end = FindNearestNode(endPoint);
        if (end == null)
            return null;
        start.G = G(start.Pos, endPoint);
        start.H = H(start.Pos, endPoint);
        open.Add(start);

        while (open.Count != 0)
        {
            //consider the best node in the open list (the node with the lowest f value)
            double d = open.Min(x => x.F);
            MyNode curr = open.First(x => x.F.CompareTo(d) == 0);
            closed.Add(curr);
            open.Remove(curr);
            //If current node is goal              
            if (curr == end)
            {
                //Loop over the parents to get the path
                List<MyNode> ns = new List<MyNode>();
                MyNode n = end;
                ns.Add(n);
                while (n != start)
                {
                    ns.Add(n.parent);
                    n = n.parent;
                }
                ns.Reverse();
                return ns;
            }
            for (int i = 0; i < curr.Edges.Count; i++)
            {
                MyNode possibleNeigbour = curr.Edges[i].NodeTo();
                if (closed.Contains(possibleNeigbour))
                {
                    //ignore it
                }
                else if (!open.Contains(possibleNeigbour))
                {
                    possibleNeigbour.G = G(possibleNeigbour.Pos, endPoint);
                    possibleNeigbour.H = H(possibleNeigbour.Pos, endPoint);
                    possibleNeigbour.parent = curr;
                    open.Add(possibleNeigbour);
                }
                else if(open.Contains(possibleNeigbour))
                {
                    if (possibleNeigbour.G < curr.G)
                    {
                        possibleNeigbour.parent = curr;
                    }
                }
            }
        }
        
        return null;
    }