Search code examples
iosswiftsprite-kitsknode

Periodically add nodes to the scene with a random time interval in between


Simplified, I'm trying to figure out how to add lets say 10 nodes to my scene over some period of time, each seperated by some random time interval.

For example:

Loop 10 times:

A. Create and add node to scene

B. Wait some random amount of time, 1-5 seconds

C. Back to A

It would nice to also know when this is finished running, to have a boolean just flip when the last node gets added to the scene, but that would require knowing when the last one finished adding. I'm not too sure how to accomplish this. I read some about dispatch_after but that wont solve my random time between adding nodes problem.


Solution

  • In SpriteKit you usually do that using SKAction and its waitForDuration(withRange:) method. Important part would be withRange parameter (quote from docs):

    Each time the action is executed, the action computes a new random value for the duration. The duration may vary in either direction by up to half of the value of the durationRange parameter.

    For example, if you have a wait duration of 3 seconds, and range parameter set to 2, you will get delays between 2 and 4 seconds.

    So here is how you could do this:

    class GameScene: SKScene, SKPhysicsContactDelegate {
    
        var lastSpawnTime:Date?
    
        override func didMove(to view: SKView) {
    
            let wait = SKAction.wait(forDuration: 3, withRange: 4)
    
            let block = SKAction.run {[unowned self] in
                //Debug
                let now = Date()
    
                if let lastSpawnTime = self.lastSpawnTime {
    
                    let elapsed = now.timeIntervalSince(lastSpawnTime)
    
                    print("Sprite spawned after : \(elapsed)")
                }
                self.lastSpawnTime = now
                //End Debug
    
                let sprite = SKSpriteNode(color: .purple, size: CGSize(width: 50, height: 50))
                self.addChild(sprite)
            }
    
            let sequence = SKAction.sequence([block, wait])
            let loop = SKAction.repeat(sequence, count: 10)
    
            run(loop, withKey: "aKey")
        }
    }
    

    And you will see in the console something like:

    Spawning after : 1.0426310300827
    Spawning after : 1.51278495788574
    Spawning after : 3.98082602024078
    Spawning after : 2.83276098966599
    Spawning after : 3.16581499576569
    Spawning after : 1.84182900190353
    Spawning after : 1.21904700994492
    Spawning after : 3.69742399454117
    Spawning after : 3.72463399171829