Search code examples
objective-ctimetimersprite-kitseconds

Objective-C: Adding 10 seconds to timer in SpriteKit


I used someone else's code for writing a timer in SpriteKit, and tweaked it a bit. Here's what my code looks like:

- (void)createTimerWithDuration:(NSInteger)seconds position:(CGPoint)position andSize:(CGFloat)size
{
    // Allocate/initialize the label node.
    _countdownClock = [SKLabelNode labelNodeWithFontNamed:@"Avenir-Black"];
    _countdownClock.fontColor = [SKColor blackColor];
    _countdownClock.position = position;
    _countdownClock.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeLeft;
    _countdownClock.fontSize = size;
    [self addChild:_countdownClock];

    // Initialize the countdown variable.
    _countdown = seconds;

    // Define the actions.
    SKAction *updateLabel = [SKAction runBlock:^{
        _countdownClock.text = [NSString stringWithFormat:@"Time Left: 0:%lu", (unsigned long)_countdown];
        _countdown--;
    }];

    SKAction *wait = [SKAction waitForDuration:1.0];

    // Create a combined action.
    SKAction *updateLabelAndWait = [SKAction sequence:@[updateLabel, wait]];

    // Run action "seconds" number of times and then set the label to indicate the countdown has ended.
    [self runAction:[SKAction repeatAction:updateLabelAndWait count:seconds] completion:^{
        _countdownClock.text = @"GAME OVER!";
        _gameOver = YES;
        [self runAction:_gameOverSound];
    }];
}

What I want to happen, is when a certain block of code is run (which I've taken care of by myself), I want to add 10 seconds to the timer.

I tried doing this, already, by adding a constant instance variable called _countTime to hold 60 seconds initially. In the -init method, I called [self createTimerWithDuration:_countTime position:_centerOfScreen andSize:24]; Inside this function, I would decrease the _countTime every time the "seconds" would decrease – in other words, every second, the _countTime would decrease. When I had the block run, the block to add 10 seconds to the time, I would remove the _countdownClock, add 10 seconds to the _countTime, and finally call createTimerWithDuration:position:andSize: again, with the update _countTime.

But this did't seem to work for me. I figured it would work fairly well. It did add 10 seconds to the time, exactly like I wanted it to, but the timer would start going down by threes. It would wait a second, then 15-14-12 BAM! Then wait a second, then 11-10-9 BAM! And so on.

So what's going on here? Was this the right approach? Is there a better way for me to increase the time, or (better yet!) a better way to create a timer, that has a function like this?


Solution

  • I believe the issue is because you are running the action on "self". Your old action is not getting removed and it is still removing time every second. Try this...

    [_countdownClock runAction:[SKAction repeatAction:updateLabelAndWait count:seconds] completion:^{
        _countdownClock.text = @"GAME OVER!";
        _gameOver = YES;
        [self runAction:_gameOverSound];
    }];
    

    and finally call createTimerWithDuration:position:andSize:

    I assume you are removing the old label before you called that again otherwise you would get some really odd looking text. When you remove _countdownClock form its parent it should also remove the action and it won't keep decreasing the time and should fix your issue.

    Hopefully that helps.