GameViewController 和 SKScenes 的区别

Difference between GameViewController and SKScenes

我一直在使用 SpriteKit 和 Swift 开发游戏,但我似乎无法确定 GameViewController 和我的任何一个 SKScene 之间的真正区别是什么秒。我试图了解其中的差异,因为我想在我的游戏中实现 GameCenter 或本地排行榜,但在我找到的所有教程中(例如 one:Game 中心排行榜!(Swift 2 in Xcode) ) 他们拥有 GameViewController 中的所有逻辑,因为他们正在使用单视图应用程序。我在阅读文档时无法理解这种关系,所以任何帮助都会很棒。最终,我希望能够在我的场景之一(例如 GameOverScene)中显示 GameCenter 数据并向 GameCenter 推送数据。感谢您的帮助!

您的游戏中应该只有一个 GameViewController。 SKScenes 是游戏在到之间转换的场景。

例如,主菜单屏幕?那是一个 SKScene。主要玩法?那是一个 SKScene。游戏结束画面?那是一个 SKScene.

GameViewController 初始化将在其中维护游戏的整个视图,因此视图。 SKScenes 只是放置在视图顶部的场景。您应该查看使用 SKScenes 的教程。

以下是如何使游戏中心在最新的 Swift 2.2.

中工作

将此函数添加到 GameViewController class 中的任意位置,然后在 super.viewDidLoad() 之后立即调用它。

func authenticateLocalPlayer() {
    let localPlayer = GKLocalPlayer.localPlayer()
    localPlayer.authenticateHandler = {(viewController, error) -> Void in

       if (viewController != nil) {
            self.presentViewController(viewController!, animated: true, completion: nil)
        }
        else {
            print((GKLocalPlayer.localPlayer().authenticated))
        }
    }
}

在您的 SKScene class 文件中添加以下函数。不要忘记导入 GameKit。每当您想要显示排行榜时,只需调用 showLeader() 即可。

func showLeader() {
    let viewControllerVar = self.view?.window?.rootViewController
    let gKGCViewController = GKGameCenterViewController()
    gKGCViewController.gameCenterDelegate = self
    viewControllerVar?.presentViewController(gKGCViewController, animated: true, completion: nil)
}
func gameCenterViewControllerDidFinish(gameCenterViewController: GKGameCenterViewController) {
        gameCenterViewController.dismissViewControllerAnimated(true, completion: nil)
}

这是我将分数保存到游戏中心的示例。

func saveHighscore(gameScore: Int) {
    print("Player has been authenticated.")
    if GKLocalPlayer.localPlayer().authenticated {
        let scoreReporter = GKScore(leaderboardIdentifier: "YOUR_LEADERBOARD_ID")
        scoreReporter.value = Int64(gameScore)
        let scoreArray: [GKScore] = [scoreReporter]

        GKScore.reportScores(scoreArray, withCompletionHandler: {error -> Void in
        if error != nil {
            print("An error has occured: \(error)")
        }
        })
    }
}

这里有一些很好的信息可以作为开始:

SK 中每一帧发生的情况图:


所以你看,SKScene 是 class 具有所有有趣的东西,如节点和动作,并且是一切(对你重要的)发生的地方。您可以通过编辑器生成这些场景,但是您可能需要制作一个新的 .swift 文件来配合它(因为每个场景都可以有自己的逻辑)。

编辑器只是 'shortcut' 初始化一堆东西,老实说,你可以用很少的代码制作完整的游戏(但你很快就会发现你 想要更多)

因此,在这段代码中,您声明 GameScene 或 PauseScreen(基本上只是 class 声明,继承自 SKScene),您很快就会发现这行代码谈论的不是场景:

override func didMoveToView(view: SKView) .. it's calling a SKView... what is that, and where did it come from?

(Read about SKView here, and look at its inheritance):

https://developer.apple.com/library/ios/documentation/SpriteKit/Reference/SKView/index.html#//apple_ref/occ/cl/SKView


我们在 GameViewController 文件中找到这个 SKView 声明(它只是一个 class),请注意它与常规 iOS 应用程序大部分相同,因为它继承了用户界面ViewController:

override func viewDidLoad() {
    super.viewDidLoad()
    if let scene = GameScene(fileNamed:"GameScene") {
        // Configure the view.
        let skView = self.view as! SKView
        skView.showsFPS = true
        skView.showsNodeCount = true

        /* Sprite Kit applies additional optimizations to improve               rendering performance */
        skView.ignoresSiblingOrder = true

        /* Set the scale mode to scale to fit the window */
        scene.scaleMode = .AspectFill

        skView.presentScene(scene)
    }

同样,该方法在 GameViewController.swift 中声明,基本上就是这样: class GameViewController: UIViewController


那么所有这些与 iOS 应用程序和 SpriteKit 有何关系?好吧,它们都被捣碎了:

IOS 应用剖析:

基本上,从右到左,您有 Window,这是(如果错误请纠正我)AppDelegate,然后是 ViewController,然后是您的视图,它具有所有很酷的功能其中的东西(情节提要位于视图内部,就像 SKScenes 位于视图内部一样......标签、节点或按钮都位于各自的 classes((视图)))

都是继承的大夹心


查看 Apple 网站了解更多信息。

https://developer.apple.com/library/safari/documentation/UserExperience/Conceptual/MobileHIG/ContentViews.html#//apple_ref/doc/uid/TP40006556-CH13-SW1

https://developer.apple.com/spritekit/

https://developer.apple.com/library/ios/documentation/SpriteKit/Reference/SpriteKitFramework_Ref/

https://developer.apple.com/library/safari/documentation/UserExperience/Conceptual/MobileHIG/Anatomy.html

基本上,一切都是 Class 继承自 class 继承自 class 等等,等等......它会变得混乱。您还可以通过 CMD + 单击它们在 Xcode 中查看这些继承,这将跳转到源文件。

祝你在 SpriteKit 中的学习和冒险顺利:)

这完全取决于您设计应用程序的方式,以及您要使用的技术。

如果您希望在 100% Sprite Kit 中构建应用程序,那么您将 UIViewController 视为一个 shell 来保存您的 Sprite Kit 应用程序。只有当你需要做 SpriteKit 场景不应该做的事情时,你才应该触及它,比如创建手势控制等等。

但是,使用带有 sprite 工具包元素的多个视图控制器是有用的。也许您正在制作一个商业应用程序,并决定在其中加入一个小游戏。

IMO 在网页设计方面考虑它的最佳方式是将您的视图控制器视为您的 HTML 页面,并将您的场景视为您嵌入的 flash/silverlight/unity/etc 游戏播放器在网站上。有时您希望该播放器全屏显示,有时您不需要,这取决于应用程序的设计。全屏时,我们不需要任何其他组件,因此播放器可以完成所有工作。但是,如果我们在页面上附加一个如何指导 link 怎么办?我们不希望在游戏中出现这种情况,我们希望在游戏之外出现这种情况。此 link 将打开一个新页面,与旧页面无关,并且对游戏玩家组件没有用处。

现在对于您使用 Game Center 的情况,它变得更加复杂。 Game Center 是在 Sprite Kit 出现之前构建的,因此它的所有功能都是基于 UIKit 构建的。但 Game Center 还允许自定义,因此您不必使用它的 UIKit 功能。当然,您必须完成所有工作,然后才能使用 Sprite Kit 对象显示场景中的信息。

为了让您的生活更轻松,您可以将所有需要的内置代码包含到您的视图控制器中,然后您要做的是创建一个场景知道的委托,并将您的视图控制器分配给该委托。现在 Game Scene 可以访问您允许的视图控制器的任何元素,例如呈现排行榜或传递排行榜。完整地查看本教程,它将帮助您了解实现您想要的目标所需的一切。 https://www.raywenderlich.com/115300/swift-2-tutorial-part-3-tuples-protocols-delegates-and-table-views

在 MVC 中,控制器充当协调器,有点像管弦乐队中的指挥。我的偏好是场景只做他们设计的一件事,即实现游戏。当一个场景完成时,最后的任务是通知控制器(使用委托模式)场景已经完成。然后由控制器决定接下来会发生什么,即过渡到下一个场景或游戏结束。