libGdx专题

寻找路径的处理思路

2021-09-07  本文已影响0人  大旺旺的弟弟小旺旺

以吃豆人为例,寻找出距离自己最近的吃豆人,然后鬼走向它,并把它吃掉。我们可以使用AStar进行寻找。每次只找出一个节点的位置,如果找不到那么就不在去寻找。而采取随机的方式寻找、
1.创建节点

    public Node(AStarMap map, int x, int y) {
        this.x = x;
        this.y = y;
        this.index = x * map.getHeight() + y;
        this.isWall = false;
        this.connections = new Array<Connection<Node>>();
    }

顶点先得到,根据坐标的长和宽将坐标编号。这个时候只是创建节点,对于里面是什么还没有做处理。
2.标记所有的墙

QueryCallback queryCallback = new QueryCallback() {
            @Override
            public boolean reportFixture(Fixture fixture) {
                wall = fixture.getFilterData().categoryBits == GameManager.WALL_BIT;
                return false; // stop finding other fixtures in the query area
            }
        };

        for (int y = 0; y < mapHeight; y++) {
            for (int x = 0; x < mapWidth; x++) {
                wall = false;
                world.QueryAABB(queryCallback, x + 0.2f, y + 0.2f, x + 0.8f, y + 0.8f);
                if (wall) {
                   aStarMap.getNodeAt(x, y).isWall = true;
                }
            }
        }

3.然后生成地图。
首先里面有墙,有路径,我们不管多余的,只管墙和路径,我们遍历所有的节点,然后检测是不是墙,是墙的就跳过,然后找出节点的上下左右,我的邻居就是什么东西,如果不是墙,我们就可以进行连接。

    public static MyGraph createGraph (AStarMap map) {
        final int height = map.getHeight();
        final int width = map.getWidth();
        MyGraph graph = new MyGraph(map);
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                Node node = map.getNodeAt(x, y);
                if (node.isWall) {
                    continue;
                } 
                // Add a connection for each valid neighbor
                for (int offset = 0; offset < NEIGHBORHOOD.length; offset++) {
                    int neighborX = node.x + NEIGHBORHOOD[offset][0];
                    int neighborY = node.y + NEIGHBORHOOD[offset][1];
                    if (neighborX >= 0 && neighborX < width && neighborY >= 0 && neighborY < height) {
                        Node neighbor = map.getNodeAt(neighborX, neighborY);
                        if (!neighbor.isWall) {
                            // Add connection to walkable neighbor
                            node.getConnections().add(new DefaultConnection<Node>(node, neighbor));
                        }
                    }
                }
                node.getConnections().shuffle();
            }
        }
        return graph;
    }

4.将可以连通的图给AStar寻路器

        this.pathFinder = new IndexedAStarPathFinder<MyNode>(createGraph(myAStarMap));
        this.connectionPath = new DefaultGraphPath<>();
        this.heuristic = new Heuristic<MyNode>() {
            @Override
            public float estimate(MyNode node, MyNode endNode) {
                return Math.abs(endNode.x - node.x)+Math.abs(endNode.y - node.y);
            }
        };

5.寻找路径

 public MyNode findNextNode(Vector2 source,Vector2 target){
        int sourceX = MathUtils.floor(source.x);
        int sourceY = MathUtils.floor(source.y);
        int targetX = MathUtils.floor(target.x);
        int targetY = MathUtils.floor(target.y);

        if (myAStarMap == null
                || sourceX < 0 || sourceX >= myAStarMap.getWidth()
                || sourceY < 0 || sourceY >= myAStarMap.getHeight()
                || targetX < 0 || targetX >= myAStarMap.getWidth()
                || targetY < 0 || targetY >= myAStarMap.getHeight()) {
            return null;
        }

        MyNode sourceNode = myAStarMap.getNodeAt(sourceX, sourceY);
        MyNode targetNode = myAStarMap.getNodeAt(targetX, targetY);
        connectionPath.clear();
        pathFinder.searchConnectionPath(sourceNode, targetNode, heuristic, connectionPath);
        return connectionPath.getCount() == 0?null : connectionPath.get(0).getToNode();

    }

开始节点 结束节点 让去找出目标路径,每次只找一个节点。

上一篇 下一篇

猜你喜欢

热点阅读