Ставить игру на паузу после активации приложения?

Это мой первый пост на этом форуме и заранее извиняюсь, если что-то не так делаю! :)

Я делаю игру для iphone с помощью Swift & SpriteKit, и в настоящее время я столкнулся с проблемой. Когда мое приложение переходит в фоновый режим, оно вызывает функцию паузы (см. ниже), но автоматически возобновляет паузу, когда игра возобновляется.

Я видел этот очень интересный пост: Spritekit - приостановить игру, когда сделалBecomeActiveКак приостановить сцену SpriteKit, когда приложение становится активным?), но я застрял.

Я не знаю, как реализовать новый класс SKView, так как мой вид настроен, как показано в приведенном ниже коде...

Вот как работает мое приложение:

class GameViewController: UIViewController {

var scene: GameScene!

override func viewDidLoad() {
    super.viewDidLoad()

    // Configure the View
    let SkView = view as! SKView
    SkView.multipleTouchEnabled = true

    // Create and configure the scene
    scene = GameScene(size: SkView.bounds.size)
    scene.scaleMode = .AspectFill

    // Present the scene
    SkView.presentScene(scene)

    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("PauseWhenBackGround:"), name:"PauseWhenBackGround", object: nil)
}

func PauseWhenBackGround(notification : NSNotification) {
    if scene.Pausing == false{
        scene.Pause()
    }
}

Я пробовал следующее:

Я добавил новый класс, который:

class GameSceneView : SKView {      
    func CBApplicationDidBecomeActive() {
    }
}

Затем я попытался установить свой вид как let SkView = view as! GameSceneView, но я получил сообщение об ошибке, говорящее, что я не могу преобразовать представление в MyProjectName.GameSceneView()... Я также пробовал следующее: let SkView! = GameSceneView() as GameSceneView!, но в итоге я получил серую фоновую сцену...

Кто-нибудь знает, как я могу реализовать новый класс SKView, чтобы предотвратить появление ошибки CBApplicationDidBecomeActive(), чтобы игра не останавливалась при активации?

Заранее большое спасибо ! :)


person CharlyStudio    schedule 06.01.2016    source источник


Ответы (1)


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

Сначала создайте мировой узел (при необходимости сделайте глобальное свойство)

 let worldNode = SKNode()
 addChild(worldNode)

Затем добавьте все спрайты, которые вам нужны, на паузу в worldNode.

 worldNode.addChild(sprite1)
 worldNode.addChild(sprite2)

Создайте перечисление для разных игровых состояний.

enum GameState {
    case Playing
    case Paused
    case GameOver
    static var current = GameState.Playing
}

Чем сделать паузу в вашей игровой сцене

 func pause() {
     GameState.current = .Paused
     //self.physicsWorld.speed = 0 // in update
     //worldNode.paused = true     // in update

     // show pause menu etc
 }

И вызовите его, как вы сделали выше, используя NSNotification или даже лучше, используя делегирование.

Я предпочитаю этот метод больше, чем приостановка сцены из gameViewController, а также приостановка всей сцены.

Создайте метод резюме

 func resume() {
        GameState.current = .Playing
        self.physicsWorld.speed = 1
        worldNode.paused = false  

        // remove pause menu etc
 }

и, наконец, добавьте это в свой метод обновления

override func update(currentTime: CFTimeInterval) {

  if GameState.current == .Paused { 
      self.physicsWorld.speed = 0
      worldNode.paused = true
}

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

Надеюсь это поможет.

person crashoverride777    schedule 06.01.2016
comment
Спасибо за ваш ответ ! Я использовал логическое значение и установил для него значение true, когда вызывается функция паузы, и когда приложение снова становится активным, я помещал это в свою функцию обновления сцены if Pausing==true && self.paused==false{self.paused=true}, поэтому игра снова ставится на паузу. Приостановка узла мира для меня проблема, так как она не останавливает физику, поэтому мой персонаж просто падает, когда узел мира останавливается! :) - person CharlyStudio; 07.01.2016
comment
Рад, что это помогло. Я просто обновляю ответ, если вы хотите использовать worldNode и приостановить физику, вам нужно установить physicsWorld.speed = 0. Таким образом, ваш парень не провалится. Я забыл это раньше. Удачного кодирования - person crashoverride777; 07.01.2016
comment
привет, тоже такая проблема! Я попробовал решение worldNode, но теперь я не могу заставить его работать! :( - person Adam; 18.01.2016
comment
у меня сенсоры работают... но... угадайте, что... вещи по-прежнему не приостанавливаются, когда я возвращаюсь в игру после выхода из приложения... я не могу этого понять?! - person Adam; 19.01.2016
comment
Итак.. я вызываю уведомление для запуска pauseGame() - person Adam; 19.01.2016
comment
функция запущена, и я печатаю на консоли - worldNode.paused, и он говорит true, но все мои спрайты все еще движутся! что происходит ?! - person Adam; 19.01.2016
comment
Вы добавили все свои спрайты в worldNode, как в worldNode.addChild. Также я забыл, что вам, вероятно, нужно установить какое-то логическое значение в true, когда игра приостановлена. Затем в вашем методе обновления скажите, если приостановлено { // приостановить игру}. Spritekit иногда возобновляет игру сам по себе, это также происходит после завершения покупки inAppPurchase. Просто установите приостановленную проверку в методе обновления. - person crashoverride777; 19.01.2016
comment
Я думаю, что у меня все получилось благодаря этому! мне пришлось ввести короткую задержку в методе обновления, иначе он слишком быстро заморозил бы все... задержка в 0,1 секунды решает проблему! Спасибо ! - person Adam; 19.01.2016
comment
говорил слишком рано, что-то (неизвестное) вызывает неприятный сбой, когда я делаю паузу - ТОЛЬКО на iPhone 4S... отлично работает на 5S и даже на iPod touch.. все работает под управлением iOS 9.2... СТРАННО! - person Adam; 19.01.2016
comment
Химхх, я так уже 2 игры и никогда не было проблем - person crashoverride777; 19.01.2016