lelephant lelephant - 2 months ago 21
Swift Question

I need help writing a Swift+SpriteKit function which will run a wait action at decreasing intervals indefinitely

So I currently have this 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


Now however I want the following to happen: 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 just runs each actions over and over again and there isn't any waiting. My output just 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
}


I have tried this a million different ways it seems. This was my last try, Can anyone else figure it out?

Thanks!

Answer

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