【AI】A star(A 星)算法在手机游戏开发中的使用
2014-07-30 16:47
513 查看
写了一个项目用到两套AI,其中一套从思路构建到实现全部由自己实现,没有参考任何资料,这个暂且不提,因为不具有广泛性,另外一套用到了A star算法,并加以修改。修改后的算法可以解决1,2,3,...,n个格子单位的位置移动问题,现在把核心代码贴出来,供参考交流
-(void)aStarBegining:(CGPoint)_startPoint{ allNodes = [[NSMutableArray alloc]init]; for (int i=0; i<32; i++) { for (int j=0; j<18; j++) { PathfindingNode *node = [[PathfindingNode alloc] initWithPosition:ccp(i, j)]; [allNodes addObject:node]; } } [self setStartCell:_startPoint]; } - (void)setStartCell:(CGPoint)_startPoint{ _start = [[PathfindingNode alloc] initWithPosition:_startPoint]; } - (BOOL)findPathFromStartNode:(PathfindingNode *)startNode toTargetNode:(PathfindingNode *)targetNode { NSMutableSet *openSet = [NSMutableSet new]; NSMutableSet *closedSet = [NSMutableSet new]; startNode.g = 0; startNode.h = [self calculateManhattanDistanceBetweenStartNode:startNode targetNode:targetNode]; startNode.f = startNode.g + startNode.h; [openSet addObject:startNode]; while ([openSet count] > 0) { PathfindingNode *node = [self lowestFScoreNodeInSet:openSet]; if ([self node:node isEqualToNode:targetNode]) { isHavePath=YES; [self reversePathFromNode:targetNode]; return YES; } else{ isHavePath=NO; } [openSet removeObject:node]; [closedSet addObject:node]; for (PathfindingNode *adjacent in [self findAdjacentSquares:node]) { if ([closedSet containsObject:adjacent]) { continue; } int g = node.g + 1; BOOL isBetter; if (![openSet containsObject:adjacent]) { [openSet addObject:adjacent]; isBetter = YES; } else if (g < adjacent.g) { isBetter = YES; } else { isBetter = NO; } if (isBetter == YES) { adjacent.parentNode = node; adjacent.g = g; adjacent.h = [self calculateManhattanDistanceBetweenStartNode:adjacent targetNode:targetNode]; adjacent.f = adjacent.g + adjacent.h; } } } return NO; } - (void)reversePathFromNode:(PathfindingNode *)endNode { for (int i=0; i<50; i++) { if ([self getChildByTag:2000+i]) { [self removeChildByTag:2000+i cleanup:YES]; } } NSMutableArray *finalPath = [NSMutableArray new]; PathfindingNode *node = endNode; int i=0; do { // CCLOG(@"X: %i, Y: %i", node.x, node.y); CCSprite *roadSp=[CCSprite spriteWithFile:@"bt.png"]; roadSp.position=ccp(node.x*32+16, node.y*32+16); roadSp.color=ccc3(0, 255, 0); [self addChild:roadSp z:5 tag:2000+(++i)]; [finalPath addObject:node]; node = node.parentNode; } while (node.parentNode != nil); _pathPointArray=finalPath; } - (int)calculateManhattanDistanceBetweenStartNode:(PathfindingNode *)currentNode targetNode:(PathfindingNode *)targetNode { int x1 = currentNode.x; int x0 = targetNode.x; int y1 = currentNode.y; int y0 = targetNode.y; int distance = abs(x1-x0) + abs(y1-y0); return distance; } - (PathfindingNode *)lowestFScoreNodeInSet:(NSMutableSet *)set { PathfindingNode *lowestScoreNode = [set anyObject]; for (PathfindingNode *node in [set allObjects]) { if (node.f < lowestScoreNode.f) { lowestScoreNode = node; } } return lowestScoreNode; } - (BOOL)node:(PathfindingNode *)node1 isEqualToNode:(PathfindingNode *)node2 { if (node1.x == node2.x && node1.y == node2.y) { return YES; } return NO; } - (NSArray *)findAdjacentSquares:(PathfindingNode *)node { NSMutableArray *squares = @[].mutableCopy; for (PathfindingNode *n in self.allNodes) { if (n.x == node.x-1 && n.y == node.y) { if (selSprite) { moveUpdatePoint.x=[self tileCoordForPosition:selSprite.position].x; moveUpdatePoint.y=[self tileCoordForPosition:selSprite.position].y; if ((map32Pix[n.x][n.y]==-1)&&!((moveUpdatePoint.x==n.x)&&(moveUpdatePoint.y==n.y))) { [squares addObject:n]; } } else { int AILoop=2; int allPointCnt=0; for (int i=0; i<AILoop; i++) { if (map32Pix[n.x][n.y-i]==-1) { allPointCnt++; } } if (allPointCnt==AILoop) { [squares addObject:n]; } } } if (n.x == node.x+1 && n.y == node.y) { if (selSprite) { moveUpdatePoint.x=[self tileCoordForPosition:selSprite.position].x; moveUpdatePoint.y=[self tileCoordForPosition:selSprite.position].y; if ((map32Pix[n.x][n.y]==-1)&&!((moveUpdatePoint.x==n.x)&&(moveUpdatePoint.y==n.y))) { [squares addObject:n]; } } else { int AILoop=2; int allPointCnt=0; for (int i=0; i<AILoop; i++) { if (map32Pix[n.x+1][n.y-i]==-1) { allPointCnt++; } } if (allPointCnt==AILoop) { [squares addObject:n]; } } } if (n.y == node.y-1 && n.x == node.x) { if (selSprite) { moveUpdatePoint.x=[self tileCoordForPosition:selSprite.position].x; moveUpdatePoint.y=[self tileCoordForPosition:selSprite.position].y; if ((map32Pix[n.x][n.y]==-1)&&!((moveUpdatePoint.x==n.x)&&(moveUpdatePoint.y==n.y))) { [squares addObject:n]; } } else { int AILoop=2; int allPointCnt=0; for (int i=0; i<AILoop; i++) { if (map32Pix[n.x+i][n.y-1]==-1) { allPointCnt++; } } if (allPointCnt==AILoop) { [squares addObject:n]; } } } if (n.y == node.y+1 && n.x == node.x) { if (selSprite) { moveUpdatePoint.x=[self tileCoordForPosition:selSprite.position].x; moveUpdatePoint.y=[self tileCoordForPosition:selSprite.position].y; if ((map32Pix[n.x][n.y]==-1)&&!((moveUpdatePoint.x==n.x)&&(moveUpdatePoint.y==n.y))) { [squares addObject:n]; } } else { int AILoop=2; int allPointCnt=0; for (int i=0; i<AILoop; i++) { if (map32Pix[n.x+i][n.y]==-1) { allPointCnt++; } } if (allPointCnt==AILoop) { [squares addObject:n]; } } } } return squares.copy; }需要注意的是,我没有把走斜线的方法贴出来,因为我在调试过程中,发现把走斜线的算法加入进去之后,玩家的从视觉上体验的效果不好,希望有心人提出想法,当然如果需要我也可以提供斜线的走法,看起来更智能
相关文章推荐
- JAVA游戏编程之三----j2me 手机游戏入门开发--俄罗斯方块_5_使用LUA脚本写游戏
- [Unity3D]手机3D游戏开发:场景切换与数据存储(PlayerPrefs 类的介绍与使用)
- [Unity3D]手机3D游戏开发:使用UnityRemote开发一个简单的FPS案例
- [Unity3D]手机3D游戏开发:如何实现最高分的存储与显示(二)----使用GUI.Box显示文字
- 游戏开发经常使用算法概述
- [Unity3D]手机3D游戏开发:如何实现最高分的存储与显示(五)----使用TextField 输入并调整排名
- 关于游戏开发中的A*/A-star的寻路算法的问题
- [Unity3D]手机3D游戏开发:如何实现最高分的存储与显示(三)----GUI Style与数组的使用
- [Unity3D]手机3D游戏开发:如何实现最高分的存储与显示(九)----使用PreviewLabs插件提速与完整的项目源码
- 手机游戏开发在印度流行使用的工具由这个国家的开发者!
- [Unity3D]手机3D游戏开发:如何实现最高分的存储与显示(七)----使用Game ID避免数据重复输入
- [Unity3D]手机3D游戏开发:如何实现最高分的存储与显示(四)----使用PlayerPrefs存储数据到本地
- [Unity3D]手机3D游戏开发:如何使用Unity3D中自带的重力感应
- 使用调色板进行手机游戏开发
- 关于使用调色板进行手机游戏的开发
- 用Eclipse开发J2ME手机游戏入门讲座
- 基于Nokia手机的移动游戏开发步步通(五)
- 基于Nokia手机的移动游戏开发步步通(四)
- 在J2ME手机程序开发中使用颜色
- 手机游戏开发综述