swift spritekit увеличивает гравитацию по ходу игры?

Я пытаюсь увеличить сложность своей игры, увеличивая гравитацию по мере роста очков игрока. Я не совсем уверен, как это реализовать, и когда я пытался использовать решение здесь: Как можно постепенно ускорить игровой процесс в Swift?

Однако я не уверен, как реализовать это в своей игре, чтобы она постепенно увеличивала гравитацию.

Вот мой код:

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

person porkchopbento    schedule 16.01.2018    source источник


Ответы (3)


Я бы воздержался от Timer здесь по нескольким причинам... Что происходит с этим решением, если игра поставлена ​​на паузу (например, сцена или вид приостановлены)? Будет ли таймер продолжать работать при возникновении различных прерываний (например, телефонный звонок или переход приложения в фоновый режим по какой-либо причине...). Будет ли этот таймер автоматически останавливаться в этих случаях и будет ли он останавливаться (также автоматически), когда приложение возвращается на передний план?

Короткий ответ: «Просто держитесь подальше от этого и используйте SKAction :)».

Длинный ответ:

Таймер не будет останавливаться/возобновляться автоматически. Он не связан с игровым циклом, таким как SKAction. Когда пользователь вернется в игру, вместо того, чтобы иметь гравитацию, как это было до прерывания, гравитация будет иметь неожиданное значение, которое, вероятно, внесет некоторый беспорядок в вашу игру. Итак, как я уже упоминал, вам нужна специальная функция паузы для класса Timer, чтобы справляться с такими ситуациями. Но, в отличие от класса Timer, в классе SKActions все это делается автоматически.

Вы также можете использовать метод обновления, но я предпочитаю действия, поэтому вот как вы можете сделать это с помощью действий:

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)
        }
    }
}
person Whirlwind    schedule 16.01.2018

Запланируйте таймер и периодически увеличивайте гравитацию, как это

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)
    } 
}
person Yakiv Kovalskyi    schedule 16.01.2018
comment
можете ли вы объяснить мне, что происходит в { _ in }? Или, может быть, указатель на то, где я могу посмотреть, чтобы понять эту часть кода? Извините, я новичок в Swift - person porkchopbento; 17.01.2018
comment
Это блок, который выполняется каждый раз, когда срабатывает таймер (в данном случае каждые 60 секунд). Это называется замыканием, и вы можете узнать больше об этом здесь. Тем не менее, вы должны использовать SKAction вместо Timer для таких вещей, как @Whirlwind, упомянутый в его ответе. - person Marcel; 17.01.2018

Почему бы не изменить гравитацию одновременно с изменением счета? Лучше всего вычислить новое значение гравитации при изменении счета и присвоить его миру в didFinishUpdate.

person Jean-Baptiste Yunès    schedule 17.01.2018