swift spritekit increase gravity as play time goes?

218 Views Asked by At

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

There are 3 best solutions below

0
On BEST ANSWER

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)
        }
    }
}
2
On

Schedule Timer and increase gravity periodically like this

override func didMove(to view: SKView) {

    let increasingDifficultyPeriod = TimeInterval(60)

    Timer.scheduledTimer(withTimeInterval: increasingDifficultyPeriod,
                         repeats: true)
    { _ in
        // increase currentGravity property here
        self.physicsWorld.gravity.dy -= CGFloat(0.1)
    } 
}
0
On

Why not changing the gravity at the same time the score changes? Best is to compute the new gravity value when the score changes and assign it to the world in didFinishUpdate.