Swift: Repeat action after a random period of time
Asked Answered
L

3

5

Previously, with Objective-C I could use performSelector: in order to repeat an action after a random period of time which could vary between 1-3 seconds. But since I'm not able to use performSelector: in Swift, I've tried using "NSTimer.scheduledTimerWithTimeInterval". And it works in order to repeat the action. But there is a problem. On set the time variable to call a function that will generate a random number. But it seems that NSTimer uses the same number every time it repeats the action.

What that means is that the action is not performed randomly, but instead, after a set period of time that is generated randomly at the beginning of the game and it is used during all the game.

The question is: Is there any way to set the NSTimer to create a random number every time it executes the action? Or should I use a different method? Thanks!

Lupine answered 7/7, 2014 at 12:20 Comment(6)
possible duplicate of Swift performSelector: withObject: afterDelay:Virg
whet if you recreate the timer in the selector which is invoked after the timer runs?Concussion
use skactions or update:, never nstimer, gcd dispatch or performselector in sprite kit or cocos2d, for details see here: https://mcmap.net/q/441334/-spritekit-creating-a-timerMichealmicheil
@LearnCocos2D Could you please help me translating that code into Swift? Thank you!Kennard
I haven't touched swift thus far....Michealmicheil
@LearnCocos2D Oh... :(Kennard
T
5

@LearnCocos2D is right... use SKActions or the update method in your scene. Here is a basic example of using update to repeat an action after a random period of time.

class YourScene:SKScene {

    // Time of last update(currentTime:) call
    var lastUpdateTime = NSTimeInterval(0)

    // Seconds elapsed since last action
    var timeSinceLastAction = NSTimeInterval(0)

    // Seconds before performing next action. Choose a default value
    var timeUntilNextAction = NSTimeInterval(4)

    override func update(currentTime: NSTimeInterval) {

        let delta = currentTime - lastUpdateTime
        lastUpdateTime = currentTime

        timeSinceLastAction += delta

        if timeSinceLastAction >= timeUntilNextAction {

            // perform your action

            // reset
            timeSinceLastAction = NSTimeInterval(0)
            // Randomize seconds until next action
            timeUntilNextAction = CDouble(arc4random_uniform(6))

        }

    }

}
Terceira answered 8/7, 2014 at 0:38 Comment(7)
What argument should I pass when calling the self.update method? Thanks for your answer!Kennard
Also, how do I delay the action? I mean, if I use this, the action is performed at the beginning, when the scene is loaded. How can I delay the update to happen, say 10 seconds after the scene is loaded? Thanks!Kennard
You will never call the update method directly. This image will show you in what order scene actions are evaluated: developer.apple.com/library/ios/documentation/GraphicsAnimation/…Terceira
The overview section here will be of help too: developer.apple.com/library/ios/documentation/SpriteKit/…Terceira
One more question. What if I want to schedule an action to happen later in the game? For example if I have one bomb dropping when the game starts I want two bombs when the user has been playing for 20 seconds or has more than 15 points. I could do that with performSelector afterDelay:x. How could I do this here?Kennard
Think of the update method as a clock. It always sends you the currentTime. It's up to you what you want to do with currentTime information. If you want to drop a bomb 20 seconds after the games starts then create a variable to store the time the game started, and track how many seconds have elapsed using your clock (currentTime). In short, you just need variables and IF statements.Terceira
Oh, interesting. I'll have to investigate. Thanks for the information and your help!Kennard
D
3

use let wait = SKAction.waitForDuration(sec, withRange: dur) in your code. SKAction.waitForDuration with withRange parameter will compute random time interval with average time = sec and possible range = dur

Dismount answered 18/8, 2015 at 5:32 Comment(0)
L
0

Generate a random time yourself and use dispatch_after to do the action.

For more information on dispatch_after, see here. Basically you can use this instead of performSelector

Lucielucien answered 7/7, 2014 at 12:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.