0

我有各种操作的优先级队列—— UIImageView 翻译和与之相关的 HP 栏减少。我已经用 CALayer 动画编写了一个 bar 小部件,所以它应该自己处理,但由于某种原因,即使我的循环是连续的,所有的动画——bar 动画以及队列中的其他动作——都同时发生。我如何强制顺序?这是我的 viewController .m 中的代码:

while (![selectedMoves isEmpty])
    {
        SelectedMove* nextMove = [selectedMoves dequeueMax];

        // Move the user to clearly indicate who is moving:
        [self animateAttacker:nextMove.user];


        [moveReporter setText:report];
        [self executeMove:nextMove];
    }

executeMove 是改变生命值以反映伤害的包装器。

-(void) executeMove:(SelectedMove*)attack
{
   ... calculate damage dealt by attack...

   // Animate HP bar change on-screen
    double percentage = (double)[currentHP intValue] / (double)[currentStats[HP] intValue];
    [playerHealthBars[slot] updateBarPercentage:percentage andMaxHP:[currentStats[HP] intValue]];


}

我的问题是所有的 healthBar 动画,以及“animateAttacker”调用,都在屏幕上同时发生。什么命令强制一个在另一个之前执行,或者在继续之前强制刷新屏幕?

animateAttacker 是根据 nextMove 将适当的 UIImage 向前转换的包装器。目标是让循环的每次迭代——生命值条和 animateAttacker——同时或按顺序执行,并按照循环的顺序执行单独的迭代:

-(void)animateAttacker:(HonmonBattleState*)attacker 
{
        UIImageView* attackerImageView = playerImages[index];
        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:1.0];
        attackerImageView.transform=CGAffineTransformMakeTranslation(ATTACK_PERTURBATION, -ATTACK_PERTURBATION);
        [UIView commitAnimations];

        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:1.0];
        attackerImageView.transform=CGAffineTransformIdentity;
        [UIView commitAnimations];
   }

谢谢你的帮助!

PS> 我可以使用 CALayer Core Animations 或 UIView 动画。我都做过,而且健康栏是在内部使用图层完成的。

4

2 回答 2

1

基于块的 UIView 动画具有可用于链接动画的完成块,请参见此处的此线程

你可以在 GitHub 上使用 CAAnimations 中的完成块和这个类别(如果你需要,它在 CocoaPods 上)。

于 2013-11-12T07:10:19.740 回答
1

如果你想要一个全局的、串行的动画队列,你应该考虑NSOperationQueue拥有一个最大并行任务数为 1 的自己的队列。这样,您在其上运行的所有操作都将延迟到之前的操作完成。

于 2013-11-12T08:18:41.230 回答