Search code examples
swiftsprite-kitinfiniteskaction

Function to run a wait action at decreasing intervals indefinitely


I have code which runs a wait action for a duration of columnTime and then runs a block of code. This results in the block running once, then wait time, then block, then wait time, etc.

func startSpawning(){
    print(columnTime)
    let wait = SKAction.waitForDuration(columnTime)
    let block = SKAction.runBlock({[unowned self] in self.spawnObstacle()})
    let sequence = SKAction.sequence([wait, block])
    runAction(SKAction.repeatActionForever(sequence), withKey: "spawning")
} //startSpawning

I want the following: wait for 5 seconds, run block code which decreases column time to 4.95 seconds, run wait for 4.95 seconds, run block code which decreases wait time to 4.90 seconds, run wait for 4.90 seconds, etc.

I tried the following but it runs each action over and over again and there isn't any waiting. My output floods with the print statements from both wait and block code blocks.

func startSpawning(){
    let wait = SKAction.runBlock({[unowned self] in self.waitFunc()})
    let block = SKAction.runBlock({[unowned self] in self.spawnObstacle()})
    let sequence = SKAction.sequence([wait, block])
    runAction(SKAction.repeatActionForever(sequence), withKey: "spawning")
} //startSpawning
func waitFunc() -> SKAction{
    print("running wait func")
    return SKAction.waitForDuration(getColumnTime())
}
func getColumnTime() -> NSTimeInterval {
    return columnTime
}

Solution

  • You are not understanding how variables work, once you assign wait to sequence, that is it. The sequence will always be whatever was assigned at the time of creation. Creating a new instance will not solve this problem, because the old one is still in the sequence. Instead of a repeat action, you need to spawn a new set of actions every time you run through the sequence:

    var columnTime : NSTimeInterval = 10
    
    func startSpawning(){
        let wait = SKAction.waitForDuration(columnTime)
        let block = SKAction.runBlock()
                    {
                        [unowned self] in 
                        columnTime -= 0.1
                        self.spawnObstacle()
                        self.startSpawning()
                    }
         let sequence = SKAction.sequence([wait, block])
         removeActionForKey("spawning")
         runAction(sequence, withKey: "spawning")
    }