解散SKScene返回到UIKit菜单
一旦我的SpriteKit游戏结束,我想回到我的UIKit MenuViewController
。 从我迄今为止学到的,使用协议/委托是最好的(?)选项,但是我一直没有能够得到这个工作。 我知道该协议可能会超过GameViewController
的类声明,看起来像这样:
protocol GameViewControllerDelegate { var gameOver: Bool? }
但是我需要帮助从GameScene
访问它,并得到它来消除GameViewController
。 下面是应用程序的骨骼,以防万一。
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!) } ...
这个SpriteKit游戏有一个MenuViewController,一个GameViewController和一个GameScene。 当你从MenuViewController按下一个button,数据通过segue发送到GameViewController。 在GameViewController呈现GameScene之前,它将数据存储在场景的userDatavariables中,以便GameScene可以访问它。 在这个例子中,这是玩家的数量。
我同意Whirwind的评论:为什么混合两个不同的框架和复杂的生活,当你可以使用一个viewController只做你所有的游戏?
无论如何,根据你的故事板截图,有2个viewControllers,你可以去第二个viewController(和GameScene
) 只有当你按下button 。
有两件事要做:取消分配当前SKScene(在你的情况GameScene
),并呈现“初始视图控制器”或你的MenuViewController
。
为此,我使用协议/委托方法的“Hello world”雪碧套件模板来扩展SKSceneDelegate
类 。 正如你所看到的,我们可以消除场景(呈现零),并调用GameViewController
上的外部方法来呈现MainViewController
为了确保这两个操作都能成功,我还使用了两个print
用于debugging:
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") } }
输出 :