Search code examples
iossprite-kitskphysicsworld

swift spritekit increase gravity as play time goes?


I am trying to increase the difficulty of my game by increasing the gravity as the player's score goes up. I am not exactly sure how to implement that and as I tried using the solution here: Any way to speed up gameplay gradually in Swift?

However, I am not sure how to implement it into my game so that it gradually increases gravity

Here's my code:

override func update(_ currentTime: TimeInterval) {
    // Altered the gravity drastically
    // self.physicsWorld.gravity = CGVector(dx: 0, dy: CGFloat(self.score))
}

Solution

  • I would stay away from Timer here because of a few reasons... What happens with that solution if the game is paused (eg scene or view is paused)? Will timer continue running when different interruptions occur (eg phone call, or having app going into background from whatever reason...). Will this timer pause automatically in those cases, and will it unpause (also automatically) when app returns to the foreground?

    The short answer is : "Just stay away from it and use SKAction :)"

    The long answer is:

    The timer will not pause / unpause automatically. It is not paired with a game loop like SKAction. When user returns to the game, instead of having a gravity like it was before the interruption, the gravity will have unexpected value which will likely make some mess in your game. So, as I mentioned, you need a custom pause feature for a Timer class to handle these situations. But, unlike in the case of Timer class, all of this is handled with SKActions automatically.

    You can use update method as well, but I prefer actions, so here is how you can do it with actions:

    import SpriteKit
    import GameplayKit
    
    class GameScene: SKScene {
    
        let kStep:CGFloat = 0.01
        let kIncreaseActionKey = "kIncreaseActionkey"
    
        override func sceneDidLoad() {
    
            let increase = SKAction.run {[unowned self] in
    
                //Optionally, you can check here if you want to increase the gravity further
                self.physicsWorld.gravity.dy -= self.kStep
                print("Gravity is now \(self.physicsWorld.gravity)")
            }
    
            let wait = SKAction.wait(forDuration: 1)//wait one second before increasing gravity
    
            let sequence = SKAction.sequence([wait, increase])
            let loop = SKAction.repeatForever(sequence)
            self.run(loop, withKey: kIncreaseActionKey)
        }
    
        override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    
            if self.action(forKey: kIncreaseActionKey) != nil{
                self.removeAction(forKey: kIncreaseActionKey)
            }
        }
    }