3

我正在创建一个简单的 XNA C# 自上而下的游戏。在游戏中,您将被一个像迷宫一样的地图周围的敌人跟踪。ATM 我已经设置好了,当游戏开始时,敌人会找到通往你的最短路径(它确实如此)。如果玩家移动了,则每秒都会找到一条新路径。

游戏总能找到一条通往你的路线,但似乎很难找到通往移动目标的最短路线,有时在你移动时会进入循环,当你停下来时,敌人会绕着地图绕半圈找到你,即使你只有几步之遥。它似乎不是启发式的,因为我删除了它(使其成为dijkstra),它似乎仍然存在同样的问题。我认为这是我忽略的简单事情,但我无法弄清楚是什么。

提前致谢

 class PathFinder
{
    private Cell[,] map = Game1.cellArray;


    public List<Cell> calculate(int currX, int currY, int destX, int destY)
    {
        resetMap();

        Debug.WriteLine("starting over");
        List<Cell> path = new List<Cell>();
        List<Cell> openList = new List<Cell>();
        List<Cell> closedList = new List<Cell>();

        Cell startPos = map[currY, currX];
        Cell endPos = map[destY, destX];
        startPos.closed = true;
        closedList.Add(startPos);


        Cell curPos = startPos;

        while (!closedList.Contains(endPos))
        {

            //add adjacent nodes to list, discover their scores
            foreach (Cell v in getAdj(curPos))
            {
                if (v.walkable == true && v.closed == false)
                {
                    if (!openList.Contains(v))
                    {
                        v.parent = curPos;
                        v.H = getH(v, endPos);
                        v.G = v.parent.G + 10;

                        v.F = v.G + v.H;
                        openList.Add(v);


                    }
                        //if square already on list would benefit from current tile being parent, make it so
                    else if (curPos.G + 10 < v.G)
                    {
                        v.parent = curPos;
                        v.G = v.parent.G + 10;
                        v.F = v.G + v.H;
                    }
                }
            }
            if (openList.Count <= 1) {/*Console.WriteLine("Returned NULL");*/ return null; }

            curPos = openList[1];

            curPos.closed = true;
            closedList.Add(curPos);
            openList[1] = openList[openList.Count - 1];
            openList.RemoveAt(openList.Count - 1);

            openList.OrderBy(o => o.F);
            openList.Reverse();

        }

        //backtrack to discover path
        Cell curNode = endPos;
        path.Add(endPos);
        while (curNode != startPos)
        {
            curNode = curNode.parent;
            path.Add(curNode);
            Debug.WriteLine("Path// X: " + curNode.xLocation + " Y: " + curNode.yLocation);
        }

        path.Reverse();
        return path;
    }
    //finds heuristic of current square by checking distance to destination ignoring walls 
    private int getH(Cell curPos, Cell endPos)
    {
        int diffX = curPos.xLocation - endPos.xLocation;
        int diffY = curPos.yLocation - endPos.yLocation;

        if (diffX < 0)
        {
            diffX *= -1;
        }
        if (diffY < 0)
        {
            diffY *= -1;
        }
        return ((diffX + diffY) * 10);
    }

    //get list of adjacent Cells
    private List<Cell> getAdj(Cell curPos)
    {
        List<Cell> adjList = new List<Cell>();

       if (curPos.xLocation - 1 >= 0){
            adjList.Add(map[curPos.yLocation, curPos.xLocation - 1]);
        }
        if (curPos.xLocation < 19)
        {
            adjList.Add(map[curPos.yLocation, curPos.xLocation + 1]);
        }
        if (curPos.yLocation - 1 >= 0)
        {
            adjList.Add(map[curPos.yLocation - 1, curPos.xLocation]);
        }
        if (curPos.yLocation < 19)
        {
            adjList.Add(map[curPos.yLocation + 1, curPos.xLocation]);
        }


        return adjList;
    }

    private void resetMap()
    {
        //reset Cells to default values
        for (int r = 0; r < map.GetLength(1); r++)
        {
            for (int c = 0; c < map.GetLength(0); c++)
            {
                map[r, c].reset();
            }
        }
    }
}
4

1 回答 1

0

刚刚解决了问题。在更改当前选定的图块之前未进行排序。我以为我给他们打分不正确,哈哈。

于 2012-12-11T17:03:26.503 回答