How to delay next action in sequence until after r

2019-09-08 07:35发布

问题:

The duration property for moveTo isn't followed when inside a runBlock, allowing the subsequent action in a sequence to get executed immediately when it should only get executed after duration seconds.

Code A (sequence properly executed):

let realDest = CGPointMake(itemA.position.x, itemA.position.y)
let moveAction = SKAction.moveTo(realDest, duration: 2.0)

itemB.runAction(SKAction.sequence([SKAction.waitForDuration(0.5), moveAction, SKAction.runBlock {
    itemB.removeFromParent()
}]))

Code B (sequence not properly executed):

let badMoveAction = SKAction.runBlock {
    let realDest = CGPointMake(itemA.position.x, itemA.position.y)
    let moveAction = SKAction.moveTo(realDest, duration: 2.0)
    itemB.runAction(moveAction)
}

itemB.runAction(SKAction.sequence([SKAction.waitForDuration(0.5), badMoveAction, SKAction.runBlock {
    itemB.removeFromParent()
}]))

In Code A, itemB gets removed after the moveAction completes (about 2 seconds). This is the correct sequence.

In Code B, itemB gets removed before badMoveAction finishes, meaning itemB never moves from its original position. It's as if the duration property isn't honored in Code B.

How can we move itemB as in Code B but ensure the next action in the sequence doesn't start until badMoveAction completes?

回答1:

runBlock of SKAction creates action with zero duration and it takes place instantaneously. So in Code B it will start executing first action and return immediately to start next action in sequence.

If you want to create your own action with duration you can use customActionWithDuration:actionBlock:. Otherwise here Code A is perfectly fine(if you want to use move action only).

Also you can use SKAction.removeFromParent() to remove itemB instead of:

SKAction.runBlock {
itemB.removeFromParent()
}

Other solution:

As runBlock executes immediately you can add waitForDuration action before removing node.(add after runBlock with duration equal to runBlock)

itemB.runAction(SKAction.sequence([SKAction.waitForDuration(0.5),
badMoveAction, SKAction.waitForDuration(2.0), SKAction.removeFromParent()]))

But this can be achieved using customActionWithDuration:actionBlock:.

If you want both action(move, remove node) should occur simultaneously then you can also use group in SKAction.