A*算法适合在静态环境中寻路,也就是说周围的物体不会动态的移动。
需要2个表,分别保存待检测和已检测的格子:
@interface AStarFinder : NSObject {
NSMutableArray *openTable;//尚未走过的格子
NSMutableArray *closeTable;//已经走过的格子
}
openTable保存的就是当前格子四周的格子(最多为8个),只保存满足条件的格子,不能是障碍物 或者出屏幕了。
你可以这样来初始化它们:
CCTMXTiledMap *map = [CCTMXTiledMap tiledMapWithTMXFile:@"tile_map.tmx"];//加载地图
<pre name="code" class="java">//mapSize是一个CGSize保存的是地图中Tile(格子)的数量
openTable = [[NSMutableArray alloc] initWithCapacity:map.mapSize.width*map.mapSize.height];
closeTable = [[NSMutableArray alloc] initWithCapacity:map.mapSize.width*map.mapSize.height];
看看A*算法的核心代码:
- (void)start:(TilePoint *)startPoint_ EndPoint:(TilePoint *)endPoint_{
[openTable addObject:startPoint_];//一开始就把起始位置放进openTable
TilePoint *curr=nil;
while ([openTable count] > 0){//该循环用来找到最短路径,openTable要是没东西了 就表示无法到达目的地!
curr = [self bestTilePoint:curr];//从openTable找取出最合适的格子,下一步应该向哪里走
if (curr != nil) {
[closeTable addObject:curr];//检测过了 就放到closeTable
if ([self nextTile:curr X:curr.x Y:curr.y-1] == YES) {//该函数用来判断是否到达终点
return;
}
......
}
看看 bestTilePoint 函数:
- (TilePoint *)bestTilePoint:(TilePoint *)p{
TilePoint *best = nil;
if ([openTable count] == 0) {
return nil;
}else {
for (NSInteger i = 0; i < [openTable count]; i++) {//遍历openTable
if (best == nil) {
best = [openTable objectAtIndex:i];//取出格子
if (best != nil && [self isComparePoint:best.parent And:p] == NO) {
best = nil;
}
}else {
TilePoint *best2 = [openTable objectAtIndex:i];
if ([self isComparePoint:best2.parent And:p] == YES) {
best = best.f >= best2.f ? best2 : best;//得到f值小的格子,f值越小路线则越可靠
}
}
}
[best retain];
[openTable removeObject:best];//从openTable中删除 一会还要加入到closeTable
return best;
}
}
总之 bestTilePoint函数就是用来找到最合适的移动方向。
看看 是如何处理每一个格子的:
- (BOOL)nextTile:(TilePoint *)curr X:(NSInteger)x Y:(NSInteger)y{
TilePoint *next = [[TilePoint alloc] createTilePoint:x Y:y];
next.parent = curr;//父亲当然是当前的格子
if ([self isComparePoint:next And:endPoint]) {//先判断是否已到目的地
[closeTable addObject:next];
NSLog(@"find end point !!!!!!!\n");
return YES; //到了目的地 就不需要在检测其它格子了。。
}
//这里检测的是格子是否为有效,包括:障碍物 出屏幕 已经检测过。。
if ([self isInCloseTable:next] == NO && [self isEnableTile:next.x Y:next.y] == YES) {
if ([self isInOpenTable:next] == NO) {
//计算f、g值
next.g = 14 + next.parent.g;
next.f = next.g + [self calculateHPower:next];
[openTable addObject:next];//然后就可以加入到openTable了
}else {
TilePoint *next2 = [self getFromOpenPath:next];
if (next2.f > next.f) {
next2.parent = curr;
next2.g = 14 + next2.parent.g;
next2.f = next2.g + [self calculateHPower:next2];
}
}
}
return NO;
}
DEMO下载
本文详细介绍了A*算法在静态环境中寻路的应用,通过使用两个表(openTable和closeTable)来跟踪路径搜索过程。核心代码包括初始化地图、开始点和结束点的设置,以及如何在openTable中寻找最优路径。此外,文中还阐述了如何处理每个节点,包括检查是否到达终点、判断节点的有效性以及更新路径等关键步骤。
1844

被折叠的 条评论
为什么被折叠?



