2014-01-08 3 views
2

Я пытаюсь переместить SKNode на экран по команде. Я установил следующую цепочку SKAction, чтобы 1) узел перемещался вверх и выключен, а затем 2) узел перемещается вниз в исходное место, затем 3) начинает перемещаться. Я использовал следующий код, чтобы попытаться осуществить это:iOS SpriteKit SKAction завершение вызова не работает/создает нечетные результаты

SKAction *moveUp = [SKAction moveTo: shipIntroSpot1 duration:3.0]; 
    SKAction *moveDown = [SKAction moveTo:shipSpot1 duration:ship1MovementSpeed]; 

    [self enumerateChildNodesWithName:@"ship1" usingBlock:^(SKNode *node, BOOL *stop) { 
     NSLog(@"RUNNING MOVE UP"); 
     [node runAction: moveUp]; 

     [node runAction:moveUp completion:^{ 
      NSLog(@"RUNNING MOVE DOWN"); 
      [node setHidden: NO]; 
      [node runAction: moveDown]; 
     }]; 

     [node runAction:moveDown completion:^{ 

      NSLog(@"STARTING MOVEMENT"); 
     }]; 

Однако SKActions не по всей видимости, стреляя в правильном порядке. Я использовал код так, чтобы как только один шаг был завершен, начнется следующее. Тем не менее, SKAction, похоже, не слишком быстро перемещает узел до начала следующего SKAction. Я был под впечатлениями, что использование вызова завершения означает, что следующее действие не начнется, пока предыдущий не завершится? Это, похоже, не так. Кроме того, если я оставлю достаточно длительную продолжительность для шага 1 (ПЕРЕМЕЩЕНИЕ), он пропустит шаг 2 (ДВИЖЕНИЕ ВНИЗ) и начнет выполнение шага 3 (ЗАПУСК ДВИЖЕНИЯ). Я понятия не имею, как это возможно. Если бы кто-нибудь мог указать на мою ошибку в понимании того, как правильно сгруппировать разные действия, я был бы признателен.

(я не делал последовательность SKAction, потому что я должен «Unhide» узел на полпути. Я не думаю, что я могу положить, что в последовательности, если я тоже не ошибаюсь об этом.)

+0

найдите последовательность действий, если вы хотите запустить одно действие за другим (последовательно). – LearnCocos2D

ответ

10

Не похоже, что вы понимаете, как выполняется runAction.

Использование

[node runAction:moveUp completion:^{ 
     NSLog(@"RUNNING MOVE DOWN"); 
     [node setHidden: NO]; 
     [node runAction: moveDown]; 
    }]; 

не просто определить завершение должно быть сделано в конце действия, но он запускает действие, а затем вызывает завершение, поэтому очень первый [узел runAction: MoveUp] потребности для удаления.

Во-вторых, вызовы runAction, которые выполняются в одной функции/блоке, будут вызываться одновременно, а так как вы вызываете [node runAction: moveUp], [node runAction: moveUp complete:] и [node runAction: moveDown завершение: ] все в одном блоке, все они будут выполняться одновременно.

Это код, который вы ищете:

SKAction *moveUp = [SKAction moveTo: shipIntroSpot1 duration:3.0]; 
SKAction *moveDown = [SKAction moveTo:shipSpot1 duration:ship1MovementSpeed]; 

[self enumerateChildNodesWithName:@"ship1" usingBlock:^(SKNode *node, BOOL *stop) { 
    NSLog(@"RUNNING MOVE UP"); 

    [node runAction:moveUp completion:^{ 
     NSLog(@"RUNNING MOVE DOWN"); 
     [node setHidden: NO]; 
     [node runAction:moveDown completion:^{ 

      NSLog(@"STARTING MOVEMENT"); 
     }]; 
    }]; 
+1

Спасибо. Это сделал трюк. В простом учебнике я наблюдал, что использование этого кода не позволило сделать это различие. – MarcZero

1

завершения запускается блок после завершения действия. Итак, если вы хотите, чтобы двигаться вверх, а затем двигаться вниз, а затем двигаться, вам необходимо написать следующий код:

[node runAction:moveUp completion:^{ 
     [node runAction:moveDown completion:^{ 
      NSLog(@"STARTING MOVEMENT"); 
     }]; 
    }]; 

То, что вы сейчас не будет работать, потому что вы называете три runAction-х подряд. Вы сначала скажите ему moveUp, но затем сразу переопределите это действие с помощью другого moveUp, на этот раз с блоком завершения, в котором вы запустите moveDown. Затем вы немедленно переопределяете это действие с помощью moveDown, так что, по существу, все, что вы делаете, говорит узлу moveDown, все остальное излишне.

1

Я знаю, что это было отмечено как ответное, но, хотя я бы предложил альтернативу.

Альтернативным вариантом было бы просто последовательности действия с помощью только одного обработчика завершения

, например (только может быть записан как один лайнер, если вы хотите):

NSArray *actions = @[moveUp, [SKAction unhide], moveDown]; 
SKAction *action = [SKAction sequence:actions]; 

затем в цикле просто напишите:

[node runAction:action withCompletion^{ 
     NSLog(@"STARTING MOVEMENT"); 
    }]; 

Надеюсь, кто-то найдет это полезным.

Смежные вопросы