In Sprite Kit do not use NSTimer
, performSelector:afterDelay:
or Grand Central Dispatch (GCD, ie any dispatch_...
method) because these timing methods ignore a node’s, scene’s or the view’s paused
state. Moreover you do not know at which point in the game loop they are executed which can cause a variety of issues depending on what your code actually does.
The only two sanctioned ways to perform something time-based in Sprite Kit is to either use the SKScene update:
method and using the passed-in currentTime parameter to keep track of time.
Or more commonly you would just use an action sequence that starts with a wait action:
id wait = [SKAction waitForDuration:2.5];
id run = [SKAction runBlock:^{
// your code here ...
}];
[node runAction:[SKAction sequence:@[wait, run]]];
And to run the code repeatedly:
[node runAction:[SKAction repeatActionForever:[SKAction sequence:@[wait, run]]]];
Alternatively you can also use performSelector:onTarget:
instead of runBlock:
or perhaps use a customActionWithDuration:actionBlock:
if you need to mimick the SKScene update:
method and don’t know how to forward it to the node or where forwarding would be inconvenient.
See SKAction reference for details.
UPDATE: Code examples using Swift
Swift 5
run(SKAction.repeatForever(SKAction.sequence([
SKAction.run( /*code block or a func name to call*/ ),
SKAction.wait(forDuration: 2.5)
])))
Swift 3
let wait = SKAction.wait(forDuration:2.5)
let action = SKAction.run {
// your code here ...
}
run(SKAction.sequence([wait,action]))
Swift 2
let wait = SKAction.waitForDuration(2.5)
let run = SKAction.runBlock {
// your code here ...
}
runAction(SKAction.sequence([wait, run]))
And to run the code repeatedly:
runAction(SKAction.repeatActionForever(SKAction.sequence([wait, run])))