Search code examples
swiftskaction

swift spritekit increase frequency of node creation as time goes on


I have figured out how to continuously spawn a node every x seconds. However, I would like to decrease the time that I wait to create a node as the game goes on, to increase the difficulty. For example, I call this function in didMoveToView:

func createSequentialEnemies(){
    runAction(SKAction.repeatActionForever(
        SKAction.sequence([
            SKAction.runBlock(createEnemy),
            SKAction.waitForDuration(2.0)
            ])
        ))
}

This creates an enemy every 2 seconds, but I want to decrease this duration arbitrarily. For example, say that after 30 seconds of gameplay I want to now spawn enemies every 1.5 seconds. How would I change the duration dynamically?


Solution

  • Create a spawnDuration property and key reference in your scene class.

    class SomeClass: SKScene {
    
           private var spawnDuration: NSTimeInterval = 2.0
           private let spawnKey = "SpawnKey"
    
    }
    

    Than adjust your spawn code to use this spawn property and key. I slightly changed the syntax as well to make it more legible in my opinion.

    func createSequentialEnemies(){
          removeActionForKey(spawnKey) // remove previous action if running. This way you can adjust the spawn duration property and call this method again and it will cancel previous action.
    
          let spawnAction = SKAction.runBlock(createEnemy)
          let spawnDelay = SKAction.waitForDuration(spawnDuration)
          let spawnSequence = SKAction.sequence([spawnAction, spawnDelay])
          runAction(SKAction.repeatActionForever(spawnSequence), withKey: spawnKey) // run action with key so you can cancel it later
    }
    

    Than you have to add some logic of when you want to change the spawn duration property you created.

    Time based could be a func like this you also call once in DidMoveToView

     func startDifficultyTimer() {
    
         let difficultyTimerKey = "DifficultyTimerKey"
    
         let action1 = SKAction.waitForDuration(30)
         let action2 = SKAction.runBlock { [unowned self] in
    
              guard self.spawnDuration > 0.2 else {  // set a min limit
                  removeActionForKey(difficultyTimerKey) // if min duration has been reached than you might as well stop running this timer.
                  return 
              } 
    
              self.spawnDuration -= 0.5 // reduce by half a second
              self.createSequentialEnemies() // spawn enemies again
    
         }
         let sequence = SKAction.sequence([action1, action2])
         runAction(SKAction.repeatActionForever(sequence), withKey: difficultyTimerKey)
     }
    

    Hope this helps