I'm trying to have a SKNode move onto the screen on command. I've set up the following SKAction chain so that 1) The node moves up and offscreen, then 2) the node moves down into a starting place, then 3) starts moving around. I've used the following code to try and implement this:
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");
}];
However, the SKActions don't appear to be firing in the correct order. I used the code so that once one step was completed, the next would start. However, the SKAction doesn't appear to move the node fast enough before the next SKAction starts working. I was under the impressions that using the completion call would mean that the next action wouldn't start until the previous one had finished? That does not appear to be the case here. In addition, if I leave a long-enough duration for step 1 (MOVING UP), it will skip over step 2 (MOVING DOWN) and start executing step 3 (STARTING MOVEMENT). I have absolutely no idea how this is possible. If anyone could point out my error in understanding how to chain different actions together properly, I would appreciate it.
(I did not do a SKAction sequence because I have to "unhide" the node halfway through. I don't think I can put that in a sequence, unless I'm wrong about that too.)
It does not seem like you understand how runAction is executed.
Using
[node runAction:moveUp completion:^{
NSLog(@"RUNNING MOVE DOWN");
[node setHidden: NO];
[node runAction: moveDown];
}];
will not just define a completion to be done at the end of the action, but it runs the action and then calls the completion, so the very first [node runAction:moveUp] needs to be removed.
Secondly, two runAction calls that are made in one function/block will be called simultaneously, and since you call [node runAction: moveUp], [node runAction:moveUp completion:] , and [node runAction:moveDown completion:] all in the same block, they will all be executed simultaneously.
This is the code you are looking for:
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");
}];
}];