您的位置:首页 > 大数据 > 人工智能

【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;
}
需要注意的是,我没有把走斜线的方法贴出来,因为我在调试过程中,发现把走斜线的算法加入进去之后,玩家的从视觉上体验的效果不好,希望有心人提出想法,当然如果需要我也可以提供斜线的走法,看起来更智能
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐