我正在尝试通过使用精灵套件制作游戏来学习xcode并且已经相对较远。我以前做过一些编程,但我很快就学会了,但经过几个小时的调试后,我几乎放弃了。
我已经构建了一个包含许多块(32x32px)和1-4个字符的地图,这些字符使用A * pathfinding来查找路径。
它有效,但我有两个问题:
正确计算路径并且char移动但是当char动画到下一个块时,有一个小paus并且他移动到下一个块。这个小小的paus让动画看起来不稳定,就像char走路一样 - > micropaus - >步行。 路径存储在nsmutablearray中,并且该方法在完成SKAction(完成)后调用自身以设置下一个动作的动画。在新动作的完成和动画之间,有这个角色的微观。
当char计算路径时,游戏会冻结一段时间。当我有4个字符时,每次计算新路径时游戏都会冻结。那是为什么?
当我单击char应该移动到的块时,我调用:
-(void)moveToward:(tileMap*)selBlock {
BOOL pathFound = NO;
if (currentStepAction) {
self.pendingMove = selBlock;
return;
}
self.StepListOpen = [NSMutableArray array];
self.StepListClosed = [NSMutableArray array];
self.shortestPath = nil;
tileMap *fromTile = self.parentBlock;
tileMap *toTile = selBlock;
[self addToOpenSteps:[[ShortestPathStep alloc] initWithBlock:fromTile]];
do {
ShortestPathStep *currentStep = [self.StepListOpen objectAtIndex:0];
[self.StepListClosed addObject:currentStep.theBlock];
[self.StepListOpen removeObjectAtIndex:0];
if (CGPointEqualToPoint(currentStep.theBlock.position, toTile.position)) {
pathFound = YES;
[self constructPathAndMove:currentStep];
self.StepListOpen = nil;
self.StepListClosed = nil;
break;
}
NSArray *adjSteps = [_scene nearbyBlocks:currentStep.theBlock];
for (tileMap *v in adjSteps) {
ShortestPathStep *step = [[ShortestPathStep alloc] initWithBlock:v];
if ([self.StepListClosed containsObject:step.theBlock]) {
continue;
}
int moveCost = [self costToMove:currentStep toAdjacentStep:step];
NSUInteger index = [self.StepListOpen indexOfObject:step.theBlock];
if (index == NSNotFound) {
step.parent = currentStep;
step.gScore = currentStep.gScore + moveCost;
CGPoint fromBlock = CGPointMake([[step.theBlock.name substringWithRange:NSMakeRange(6,1)] floatValue], [[step.theBlock.name substringWithRange:NSMakeRange(8,1)] floatValue]);
CGPoint toBlock = CGPointMake([[toTile.name substringWithRange:NSMakeRange(6,1)] floatValue], [[toTile.name substringWithRange:NSMakeRange(8,1)] floatValue]);
step.hScore = [self computeHscore:fromBlock toCoord:toBlock];
[self addToOpenSteps:step];
} else {
step = [self.StepListOpen objectAtIndex:index];
if ((currentStep.gScore + moveCost) < step.gScore) {
step.gScore = currentStep.gScore + moveCost;
[self.StepListOpen removeObjectAtIndex:index];
[self addToOpenSteps:step];
}
}
}
} while ([self.StepListOpen count] > 0);
if (!pathFound) {
NSLog(@"No path found.");
}
}
如果找到它调用的路径
- (void)constructPathAndMove:(ShortestPathStep *)step {
self.shortestPath = [NSMutableArray array];
do {
if (step.parent != nil) {
[self.shortestPath insertObject:step atIndex:0];
}
step = step.parent;
} while (step != nil);
[self popStepAndAnimate];
}
现在我们转到popStepAndAnimate,这是一遍又一遍地调用的方法,直到char到达目的地为止。
-(void)popStepAndAnimate {
self.currentStepAction = nil;
if (self.pendingMove != nil) {
tileMap *moveTarget = pendingMove;
self.pendingMove = nil;
self.shortestPath = nil;
[self moveToward:moveTarget];
return;
}
if (self.shortestPath == nil) {
return;
}
// WE HAVE REACHED OUR BLOCK! CHECK IF ITS CLICKED OR STROLLING
if ([self.shortestPath count] == 0) {
self.shortestPath = nil;
return;
}
ShortestPathStep *s = [self.shortestPath objectAtIndex:0];
CGPoint futurePosition = s.theBlock.position;
CGPoint currentPosition = self.parentBlock.position;
CGPoint diff = ccpSub(futurePosition, currentPosition);
if (abs(diff.x) > abs(diff.y)) {
if (diff.x > 0) { [self runAnimation:_faceRight speed:0.1]; } else { [self runAnimation:_faceLeft speed:0.1]; }
} else {
if (diff.y > 0) { [self runAnimation:_faceUp speed:0.2]; } else { [self runAnimation:_faceDown speed:0.2]; }
}
self.parentBlock = s.theBlock;
SKAction *moveAction = [SKAction moveTo:s.theBlock.position duration:0.7];
SKAction *callbackAction = [SKAction runBlock:^{ [self popStepAndAnimate]; }];
self.currentStepAction = [SKAction sequence:@[moveAction, callbackAction]];
[self.shortestPath removeObjectAtIndex:0];
[self runAction:currentStepAction];
}