How to implement A * pathfinding Algorithm in Cocos2D games (2)
Cat maze and A * Overview
As you can see, when you touch somewhere on the map, the cat will jump to the adjacent bucket in the direction of your touch.
We want to change it to the continuous movement of the cat until you click the position, just like some RPG games or adventure games you click.
Let's take a look at how the current touch processing code works. If you open HelloWorldLayer, you will find that it implements touch callback like the following code:
- (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;}
You can see that it only calls a method in cat sprite, allowing the cat to move toward the touch point on the map.
Therefore, we will modify the following methods in CatSprite. m to find the shortest path of the target point, as shown below:
- (void)moveToward:(CGPoint)target { // Figure out the shortest path to the target, and start following it!}
Create a ShortestPathStep class
Let's start from creating an internal class of step in the description path. in our example, this is A tile, and its F, G, and H values are calculated by the * algorithm.
So add the following code to the beginning of CatSprite. m (above @ implementation of CatSprite ):
// 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
As you can see, this is a very simple class, where tracing saves the following content:
Coordinate score G of the tile (Note: Here is the number of tiles from the start position to the current position) value H (Note: Here it is the estimated number of tiles from the current end position) where is the ShortestPathStep value F, which is the value of the tile (Calculated using F + G ).
Now we can write the implementation code at the end of CatSprite. m (under @ 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
As you can see, the content is very straightforward. we have redefined the description method here to make it easier to debug and create an isEqual method, because the two shortestpathsteps are the same only when their posititon is the same (for example: they represent the same tile ).