解雇SKScene回到UIKit菜单 [英] dismiss SKScene go back to UIKit Menu

查看:106
本文介绍了解雇SKScene回到UIKit菜单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一旦我的SpriteKit游戏结束,我想回到我的 UIKit MenuViewController 。从我到目前为止所学到的,使用 协议/委托 是最好的(?)选项,但我无法让它工作。我知道协议可能会超过 GameViewController 的类声明,看起来像这样:

 协议GameViewControllerDelegate {
var gameOver:Bool?
}

但我需要帮助从 GameScene 并让它解雇 GameViewController 。以下是该应用程序的骨骼,如果有帮助的话。





MenuViewController

 类MenuViewController:UIViewController {

覆盖func viewDidLoad (){
super.viewDidLoad()
}

@IBAction func goToGame(_ sender:UIButton){
performSegue(withIdentifier:toGameSegue,sender: sender.currentTitle)
}

覆盖func prepare(对于segue:UIStoryboardSegue,sender:Any?){
如果让destinationVC = segue.destination为? GameViewController {
如果让item = sender为?字符串{
destinationVC.numberOfPlayers = item
}
}
}
}

GameViewController

  class GameViewController:UIViewController {

var numberOfPlayers:String?

覆盖func viewDidLoad(){
super.viewDidLoad()

如果让view = self.view为! SKView? {
if let scene = SKScene(fileNamed:GameScene){
scene.scaleMode = .aspectFill

scene.userData = NSMutableDictionary()
scene.userData ?。setObject(numberOfPlayers!,forKey:numberOfPlayersas NSCopying)

view.presentScene(scene)
}
}
}
.. 。

GameScene

  class GameScene:SKScene {

var howManyPlayers:String?

覆盖func didMove(查看:SKView){

如果让numPlayers = self.userData?.value(forKey:numberOfPlayers){
howManyPlayers = numPlayers为?字符串
}

打印(howManyPlayers!)

}
...

这款SpriteKit游戏有一个MenuViewController,一个GameViewController和一个GameScene。当您从MenuViewController按下按钮时,数据将通过segue发送到GameViewController。在GameViewController呈现GameScene之前,它将数据存储在scene的userData变量中,以便GameScene可以访问它。在这个例子中,它是玩家的数量。

解决方案

我同意Whirwind评论:为什么混合两个不同的框架并使你的生活变得复杂,你只能使用一个viewController来完成所有工作你的游戏?



无论如何,根据你的故事板截图,有2个viewControllers,你可以去第二个viewController(和 GameScene 仅当您按下按钮时。



有两件事要做:取消分配当前的SKScene(在您的情况下为 GameScene )并显示初始视图控制器或你的 MenuViewController



要做到这一点,我使用Hello world 带有协议/委托方法的Sprite-kit模板,用于扩展 SKSceneDelegate


Once my SpriteKit game has ended, I would like to go back to my UIKit MenuViewController. From what I've learned so far, using protocol/delegate is the best(?) option, but I haven't been able to get that to work. I know that the protocol would probably go above the class declaration for GameViewController, and look something like:

protocol GameViewControllerDelegate {
    var gameOver: Bool?
}

But I need help accessing that from GameScene AND getting it to dismiss GameViewController. Below are the bones of the app, in case that helps.

MenuViewController

class MenuViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func goToGame(_ sender: UIButton) {
        performSegue(withIdentifier: "toGameSegue", sender: sender.currentTitle)
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let destinationVC = segue.destination as? GameViewController {
            if let item = sender as? String {
                destinationVC.numberOfPlayers = item
            }
        }
    }
}

GameViewController

class GameViewController: UIViewController {

    var numberOfPlayers: String?

    override func viewDidLoad() {
        super.viewDidLoad()

        if let view = self.view as! SKView? {
            if let scene = SKScene(fileNamed: "GameScene") {
                scene.scaleMode = .aspectFill

                scene.userData = NSMutableDictionary()
                scene.userData?.setObject(numberOfPlayers!, forKey: "numberOfPlayers" as NSCopying)

                view.presentScene(scene)
            }
        }
    }
...

GameScene

class GameScene: SKScene {

    var howManyPlayers: String?

    override func didMove(to view: SKView) {

        if let numPlayers = self.userData?.value(forKey: "numberOfPlayers") {
            howManyPlayers = numPlayers as? String
        }

        print(howManyPlayers!)

    }
...

This SpriteKit game has a MenuViewController, a GameViewController, and a GameScene. When you press a button from MenuViewController, data is sent via segue to GameViewController. Before GameViewController presents GameScene it stores the data in scene's userData variable so that GameScene can access it. In this example, it's the number of players.

解决方案

I agree with Whirwind comment's: why mixing two different frameworks and complicate your life when you can use one viewController only to do all your game?

Anyway, according to your storyboard screenshot,there are 2 viewControllers and you can go to the second viewController (and to the GameScene) only if you press a button.

There are two things to do: deallocate the current SKScene (in your case the GameScene) and present the "initial view controller" or your MenuViewController.

To do it, I use the "Hello world" Sprite-kit template with a protocol/delegate approach to extend the SKSceneDelegate class. As you can see we able to dismiss the scene (presenting nil) and call an external method on the GameViewController to present the MainViewController

To be sure that both of these operations go to be successful I use also two print just for debug:

GameViewController:

import UIKit
import SpriteKit
class GameViewController: UIViewController,TransitionDelegate {
    override func viewDidLoad() {
        super.viewDidLoad()
        if let view = self.view as! SKView? {
            if let scene = SKScene(fileNamed: "GameScene") {
                scene.scaleMode = .aspectFill
                scene.delegate = self as TransitionDelegate
                view.presentScene(scene)
            }
            view.ignoresSiblingOrder = true
            view.showsFPS = true
            view.showsNodeCount = true
        }
    }
    func returnToMainMenu(){
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        guard  let storyboard = appDelegate.window?.rootViewController?.storyboard else { return }
        if let vc = storyboard.instantiateInitialViewController() {
            print("go to main menu")
            self.present(vc, animated: true, completion: nil)
        }
    }
}

GameScene:

import SpriteKit
protocol TransitionDelegate: SKSceneDelegate {
    func returnToMainMenu()
}
class GameScene: SKScene {
    override func didMove(to view: SKView) {
        self.run(SKAction.wait(forDuration: 2),completion:{[unowned self] in
            guard let delegate = self.delegate else { return }
            self.view?.presentScene(nil)
            (delegate as! TransitionDelegate).returnToMainMenu()
        })
    }
    deinit {
        print("\n THE SCENE \((type(of: self))) WAS REMOVED FROM MEMORY (DEINIT) \n")
    }
}

Output:

这篇关于解雇SKScene回到UIKit菜单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆