寻找路径的处理思路
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();
}
开始节点 结束节点 让去找出目标路径,每次只找一个节点。