A *算法的

时间:2017-05-31 08:09:32

标签: java

在瞬间,我使用寻路来在(仍然很小的)平铺图上导航我的单位,进行2D策略游戏。瓷砖是32x32,地图是50x100大,所以非常小:)。它到目前为止一切都工作但我有更多的滞后,我创建的单位越多。直到30个单位,它应该工作,但更多使我的程序lagg非常强大。

所以我使用ArrayList作为我的openSet和(在做了一些谷歌搜索后)我知道这很糟糕。所以我需要使用TreeSet对我的openList进行排序,但是使用TreeSet来覆盖compareTo()。我不适合这样的比较。

我必须准确比较什么,f值或Signum?我不知道,我需要一些帮助。

这是A *算法:

public static List<Tile> findPath(int startx,int starty,int endx,int endy){

    for(int i = 0; i < width; i++){
        for(int j = 0;j < height;j++){
            tiles[i][j] = new Tile(i,j,size,size,obstacles[i][j],false);
        }
    }

    for(int i = 0; i < width; i++){
        for(int j = 0;j < height;j++){
            tiles[i][j].addNeighbours(tiles,width,height);
        }
    }

    List<Tile> openList = new ArrayList<Tile>(); // Here i want a TreeSet
    HashSet<Tile> closedList = new HashSet<Tile>();
    List<Tile> path = null;

    Tile start = tiles[startx][starty];
    Tile end = tiles[endx][endy];

    Tile closest = start;
    closest.h = heuristic(closest,end);

    openList.add(start);

    while(!openList.isEmpty()) {

        int winner = 0;
        for (int i = 0; i < openList.size(); i++) {
            if (openList.get(i).f < openList.get(winner).f) {
                winner = i;
            }
        }

        Tile current = openList.get(winner);

        openList.remove(current);

        if (current == end) {
            path = new ArrayList<Tile>();
            Tile tmp = current;
            path.add(tmp);
            while (tmp.previous != null) {
                path.add(tmp);
                tmp = tmp.previous;
            }
            return path;
        }

        closedList.add(current);

        List<Tile> neighbours = current.neighbours;

        for (int i = 0; i < neighbours.size(); i++) {
            Tile neighbour = neighbours.get(i);
            int cost = current.g + heuristic(current,neighbour);
            if (openList.contains(neighbour) && cost < neighbour.g) {
                openList.remove(neighbour);
            }
            if (closedList.contains(neighbour) && cost < neighbour.g) {
                closedList.remove(neighbour);
            }
            int newcost = heuristic(neighbour, end);
            if (!openList.contains(neighbour) && !closedList.contains(neighbour) && !neighbour.obstacle) {
                neighbour.h = newcost;
                if (neighbour.h < closest.h) {
                    closest = neighbour;
                }
            }
            if (!openList.contains(neighbour) && !closedList.contains(neighbour) && !neighbour.obstacle) {
                neighbour.g = cost;
                openList.add(neighbour);
                neighbour.f = neighbour.g + neighbour.h;
                neighbour.previous = current;
            }
        }
    }
    Tile tmp = closest;
    path = new ArrayList<Tile>();
    path.add(tmp);
    while (tmp.previous != null) {
        path.add(tmp);
        tmp = tmp.previous;
    }
    return path;
}

public static int heuristic(Tile A,Tile B) {
    int dx = Math.abs(A.x - B.x);
    int dy = Math.abs(A.y - B.y);
    return 1 * (dx + dy) + (1 - 2 * 1) * Math.min(dx,dy);
}

我有另一个问题。我在调用finPath-Method期间加载整个地图包含ist障碍,但我没有找到另一个解决方案,我只能加载一次。而且我真的很想相信我......

所以这是我的两个问题:

  1. 在compareTo方法中我必须完全比较什么才能使它有效?
  2. 我在哪里可以加载我的TiledMap一次,所以A *在调用它时没有更新它?

0 个答案:

没有答案