Xcode 精灵套件+A*寻路=颠簸和冻结
我试图通过使用精灵工具包制作一个游戏来学习xcode,并且已经取得了相对的进步。我以前做过一些编程,我学得很快,但在调试了几个小时的游戏后,我几乎放弃了 我已经构建了一个包含大量块32x32px和1-4个字符的地图,它使用*寻路来查找路径 它可以工作,但我有两个问题: 路径计算正确,角色移动,但当角色设置动画到下一个块时,会有一点停顿,他会移动到下一个块。这个小停顿使动画看起来像是起伏的,就像char正在行走->微停顿->行走。 路径存储在nsmutablearray中,该方法在完成SKAction完成后调用自身以设置下一步的动画。在新动作的完成和动画制作之间,角色会出现这种微停顿 当char计算出一条路径时,游戏会冻结一段时间。当我有4个角色时,每次计算新路径时,游戏都会冻结。为什么呢 当我单击字符应该移动到的块时,我调用:Xcode 精灵套件+A*寻路=颠簸和冻结,xcode,sprite-kit,freeze,path-finding,Xcode,Sprite Kit,Freeze,Path Finding,我试图通过使用精灵工具包制作一个游戏来学习xcode,并且已经取得了相对的进步。我以前做过一些编程,我学得很快,但在调试了几个小时的游戏后,我几乎放弃了 我已经构建了一个包含大量块32x32px和1-4个字符的地图,它使用*寻路来查找路径 它可以工作,但我有两个问题: 路径计算正确,角色移动,但当角色设置动画到下一个块时,会有一点停顿,他会移动到下一个块。这个小停顿使动画看起来像是起伏的,就像char正在行走->微停顿->行走。 路径存储在nsmutablearray中,该方法在完成SKActi
-(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.");
}
}
现在我们转到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];
}
正如您在问题中提到的,您应该提供相关的代码,这样社区才能看到哪里出了问题。只要你有时间,请阅读帮助中心的部分。可能值得发布一些调用路径查找算法的代码。HMI在出错的地方添加了一些代码:感谢我能得到的每一点帮助。几天来一直试图让它更平滑,没有冻结的经验:D
-(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];
}