我正在使用Sprite Kit构建一个实现A * Pathfinding的游戏。我正在使用角色用来计算路径的网格系统(块),效果很好。我的问题是动画。
我正在使用NSMutableArray来保存步骤,并在每次移动完成后删除一个步骤(runAction完成)。它有效,但动画在完成和新动作之间冻结了一微秒,使它看起来“波涛汹涌”,这不是一个平稳的动作......
我已经尝试了很多东西,唯一有用的是将持续时间改为大约1.5秒以移动32px(它将成为一个懒人游戏;))。当我想要我需要的持续时间(0.7)时,就会出现问题。
我真的希望有人可以帮助我。
以下是一些代码:
-(void)animateChar {
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;
self.moving = FALSE;
self.strolling = FALSE;
if (self.minionBlock) {
CGPoint diff = ccpSub(self.minionBlock.position, self.parentBlock.position);
if (abs(diff.x) > abs(diff.y)) {
if (diff.x > 0) { [self runAnimation:_faceRight speed:0.3]; } else { [self runAnimation:_faceLeft speed:0.3]; }
} else {
if (diff.y > 0) { [self runAnimation:_faceUp speed:0.3]; } else { [self runAnimation:_faceDown speed:0.3]; }
}
// SET TIMER FOR REMOVING THE BLOCK. EVERY 0.5 SECONDS IT REMOVES X ENDURANCE.
self.blockTimer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(pickBlock) userInfo:nil repeats:YES];
} else {
[self setMinionBusy:FALSE];
[self runAnimation:_waiting speed:0.3];
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(selectRandBlockAndMove) userInfo:nil repeats:NO];
}
return;
}
ShortestPathStep *s = [self.shortestPath objectAtIndex:0];
// CHECK HOLE ON NEXT DOWN
tileMap *checkHole = [s.theBlock getNeighbor:1];
if ([checkHole isBlockType] == 2) { // THERE IS A HOLE, WE CANT REACH!
if ([_scene getRecentBlock] == self.minionBlock) { [_scene controlHud:1]; }
[self removeBlockBar];
[self.minionBlock setOccupied:FALSE];
self.minionBlock = nil;
self.currentStepAction = nil;
self.pendingMove = nil;
self.shortestPath = nil;
[self runAnimation:_waiting speed:0.3];
[self addBubble:1];
if (!self.stuck) {
[NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(selectRandBlockAndMove) userInfo:nil repeats:NO];
}
return;
}
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.2]; } else { [self runAnimation:_faceLeft speed:0.2]; }
} else {
if (diff.y > 0) { [self runAnimation:_faceUp speed:0.2]; } else { [self runAnimation:_faceUp speed:0.2]; }
}
self.parentBlock = s.theBlock;
currentStepAction = [SKAction moveTo:s.theBlock.position duration:1.2];
[self runAction:currentStepAction completion:^{
[self animateChar];
}];
[self.shortestPath removeObjectAtIndex:0];
}
答案 0 :(得分:0)
您可以尝试以动画序列的形式执行完成:
[self runAction:[SKAction sequence:@[currentStepAction,
[SKAction runBlock:^{ [self animateChar]; }]
]]];
在制作动画时SKAction中止时,也不会调用animateChar
。