isPaused не работает должным образом в SKNode () - PullRequest
0 голосов
/ 30 апреля 2018

Я делаю карточную игру со Swift 4 и SpriteKit. Я создал собственный подкласс SKScene, и внутри этого класса есть SKNode, который я использую в качестве слоя (gameLayer), к которому я присоединяю все узлы, которые должны быть остановлены.

Я также сделал кнопку, которая вызывает функцию (pauseGame), которая переключает isPaused из gameLayer, который отлично работает.

Проблема в том, что я хочу, чтобы когда игра перемещалась на сцену, она начиналась уже остановленной, пользователь должен начать игру, нажав кнопку. Но когда я вызываю функцию pauseGame внутри функции didMove, она не работает, gameLayer остается активным.

Я сделал несколько замечаний, помещая «print (gameLayer.isPaused)» и количество кадров в функцию обновления. Это показало, что на самом деле сцена начинается с gameLayer.isPaused, установленным в true внутри didMove, как и должно быть, но после 2-го кадра она получает значение false. Я действительно понятия не имею, где это может произойти, так как я не обращаюсь к gameLayer.isPaused где-либо еще в коде.

Конечно, решением было бы вызвать pauseGame после 2-го кадра, но я думаю, что это не чистый способ.

class BMScene: SKScene {
      let gameLayer = SKNode() 

    func pauseGame(){
      if gameLayer.isPaused {
        gameLayer.isPaused = false
      } else {
        gameLayer.isPaused = true
          }
    }

    override func didMove(to view: SKView) {
    self.pauseGame()
    }

1 Ответ

0 голосов
/ 30 апреля 2018

isPaused - ошибка в мире SpriteKit. Я в буквальном смысле поспорил с разработчиками в Apple о его нарушенной природе, и они утверждают, что именно так оно и должно работать, и мы должны с этим справиться. Последнее злодеяние, о котором я знаю, это то, что isPaused по умолчанию устанавливается в true для новых сцен, а затем отправляется сообщение, чтобы остановить его. Кроме того, когда вы отключаете родительский узел, он также останавливает все дочерние узлы.

Таким образом, в вашем коде здесь переопределите isPaused вашей сцены, чтобы иметь возможность захватить событие приостановки, чтобы заблокировать его переход к дочерним элементам

class BMScene: SKScene {
    let gameLayer = SKNode() 
    private var _paused : Boolean = false
    override var isPaused : Boolean
    {
        get
        {
            return _paused
        }
        set
        {
           _paused = newValue
        }
    }
    func pauseGame(_ state: Boolean? = null){
        gameLayer.isPaused = state ?? !gameLayer.isPaused
    }

    override func didMove(to view: SKView) {
        self.pauseGame(true)
    }
}

Это остановит ваш узел от изменения состояния паузы для детей. После этого момента вы должны полностью контролировать состояние паузы gameLayer, и оно должно отображаться так, как вы думаете.

Я также изменил вашу функцию, чтобы вы могли форсировать состояние паузы, а также переключаться, когда вы хотите поменять состояние.

* 1013 Е.Г. *

Pause:
pauseGame(true)
'gameLayer.isPaused is now true
Unpause:
pauseGame(true)
'gameLayer.isPaused is now false
Toggle:
pauseGame()
'gameLayer goes from false to true, or true to false

?? Означает COALESCE, поэтому, если state равно нулю, оно будет перемещаться по цепочке к следующему значению, которое равно !gameLayer.isPaused

...