How can I create a timer that fires every two seconds that will increment the score by one on a HUD I have on my screen? This is the code I have for the HUD:
@implementation MyScene { int counter; BOOL updateLabel; SKLabelNode *counterLabel; } -(id)initWithSize:(CGSize)size { if (self = [super initWithSize:size]) { counter = 0; updateLabel = false; counterLabel = [SKLabelNode labelNodeWithFontNamed:@"Chalkduster"]; counterLabel.name = @"myCounterLabel"; counterLabel.text = @"0"; counterLabel.fontSize = 20; counterLabel.fontColor = [SKColor yellowColor]; counterLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeCenter; counterLabel.verticalAlignmentMode = SKLabelVerticalAlignmentModeBottom; counterLabel.position = CGPointMake(50,50); // change x,y to location you want counterLabel.zPosition = 900; [self addChild: counterLabel]; } }
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])))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With