【Objective-c算法】 A*自动寻路算法

本文详细介绍了A*算法在静态环境寻路过程中的实现细节,包括地图加载、初始化开放表与关闭表、核心循环逻辑以及如何通过bestTilePoint函数找到最优路径。重点突出了如何处理每个格子的有效性检查,以及如何更新开放表与关闭表以优化寻路效率。

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下载

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值