猫咪迷宫和A*概述
正如你所看到的,现在当你在地图某处触摸的时候,猫咪将会跳到你触摸方向的相邻瓦格中去.
我们想要修改为猫咪连续移动直到你点击的位置,就像一些RPG或者点击的探险游戏一样.
让我们看一下当前触摸处理代码是如何工作的.如果你打开HelloWorldLayer,你将发现其像下面代码一样实现触摸回调:
- (void)registerWithTouchDispatcher {
[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];
}
- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
if (_gameOver) return NO;
CGPoint touchLocation = [_tileMap convertTouchToNodeSpace:touch];
[_cat moveToward:touchLocation];
return YES;
}
你可以看到它仅仅调用了cat sprite中的一个方法,让猫咪在地图上朝着触摸的点方向去移动.
所以我们将去修改CatSprite.m中的以下方法去找寻到目的点的最短路径,如下所示:
- (void)moveToward:(CGPoint)target {
// Figure out the shortest path to the target, and start following it!
}
创建ShortestPathStep类
让我们从创建一个描述路径中的step的内部类中开始.在我们的例子中,这是一个瓦块,并且它的F,G和H分值都由A*算法来计算.
So添加以下代码到CatSprite.m的开头(在CatSprite的@implementation之上):
// A class that represents a step of the computed path
@interface ShortestPathStep : NSObject
{
CGPoint position;
int gScore;
int hScore;
ShortestPathStep *parent;
}
@property (nonatomic, assign) CGPoint position;
@property (nonatomic, assign) int gScore;
@property (nonatomic, assign) int hScore;
@property (nonatomic, assign) ShortestPathStep *parent;
- (id)initWithPosition:(CGPoint)pos;
- (int)fScore;
@end
正如你所见的,这是一个非常简单的类,其中跟踪保存了以下内容:
- 瓦块的坐标
- 分值G(注意,在这里是开始到当前位置的瓦片个数)
- 分值H(注意,在这里它是当前到结束位置估计的瓦块数量)
- ShortestPathStep来自哪里
- 分值F,就是该瓦块的分值(用F + G来计算).
现在我们可以在CatSprite.m最后(在@end下面)写出实现代码:
@implementation ShortestPathStep
@synthesize position;
@synthesize gScore;
@synthesize hScore;
@synthesize parent;
- (id)initWithPosition:(CGPoint)pos
{
if ((self = [super init])) {
position = pos;
gScore = 0;
hScore = 0;
parent = nil;
}
return self;
}
- (NSString *)description
{
return [NSString stringWithFormat:@"%@ pos=[%.0f;%.0f] g=%d h=%d f=%d", [super description], self.position.x, self.position.y, self.gScore, self.hScore, [self fScore]];
}
- (BOOL)isEqual:(ShortestPathStep *)other
{
return CGPointEqualToPoint(self.position, other.position);
}
- (int)fScore
{
return self.gScore + self.hScore;
}
@end
正如你看到的那样,其内容非常直截了当.我们在这里重新定义了description方法,为的是更容易去调试,并且创建了一个isEqual方法,因为2个ShortestPathStep只有在它们的posititon相同时才相同(比如:它们表示同一个瓦块).