4

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!

José María
  • 2,563
  • 5
  • 23
  • 40

3 Answers3

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))

        }

    }

}
Jon
  • 2,980
  • 1
  • 15
  • 28
  • What argument should I pass when calling the self.update method? Thanks for your answer! – José María Jul 08 '14 at 14:12
  • 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! – José María Jul 08 '14 at 15:01
  • You will never call the update method directly. This image will show you in what order scene actions are evaluated: https://developer.apple.com/library/ios/documentation/GraphicsAnimation/Conceptual/SpriteKit_PG/Introduction/Introduction.html#//apple_ref/doc/uid/TP40013043-CH1-SW1 – Jon Jul 08 '14 at 15:59
  • The overview section here will be of help too: https://developer.apple.com/library/ios/documentation/SpriteKit/Reference/SKScene_Ref/Reference/Reference.html – Jon Jul 08 '14 at 16:00
  • 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? – José María Jul 09 '14 at 10:05
  • 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. – Jon Jul 09 '14 at 14:58
  • Oh, interesting. I'll have to investigate. Thanks for the information and your help! – José María Jul 09 '14 at 21:18
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

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

Community
  • 1
  • 1
Roshan
  • 1,927
  • 1
  • 12
  • 24