GameViewController和SKScenes之间的区别

时间:2016-08-25 18:00:02

标签: swift uiviewcontroller sprite-kit gamekit game-center-leaderboard

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

4 个答案:

答案 0 :(得分:5)

以下是一些很好的信息:

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

enter image description here

所以你看,SKScene是一个包含节点和动作等所有有趣内容的类,并且是一切(对你很重要)发生的地方。您可以通过编辑器生成这些场景,但是您可能需要创建一个新的.swift文件(因为每个场景都有自己的逻辑)。

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

所以在这段代码中,你声明了GameScene或PauseScreen(它们基本上只是类声明,继承自SKScene),你很快就会发现这一行谈论ISNT是一个场景:

  

override func didMoveToView(view: SKView)   ..它正在调用SKView ......那是什么,它来自哪里?

     

(在这里阅读SKView,看看它的继承):

     

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

我们在GameViewController文件中找到这个SKView声明(这只是一个类),注意它与普通的iOS应用程序大致相同,因为它继承了UIViewController:

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 app解剖:

anatomy

基本上,从右到左,你有一个Window,它是(如果错误的话,我是错误的)AppDelegate,然后是ViewController,然后你的View,里面有所有很酷的东西(Storyboards位于View里面)就像SKScenes坐在View ....标签,节点或按钮内部一样,都位于各自的类中((视图)))

这都是遗产的三明治。

查看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

基本上,一切都是继承自类继承的类的类,依此类推......它可能会变得混乱。你也可以通过CMD +点击它们在Xcode中看到这些遗产,这会将你跳转到源文件。

Goodluck与你在SpriteKit的学习和冒险:)

答案 1 :(得分:4)

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

例如,主菜单屏幕?这是一个SKScene。主要的游戏玩法?这是一个SKScene。游戏画面?这是一个SKScene。

GameViewController初始化游戏将保留的整个视图,因此视图。 SKScenes只是置于视图顶部的场景。您应该查看使用SKScenes的教程。

这里是如何让游戏中心像最新的Swift 2.2一样工作。

在GameViewController类中的任何位置添加此函数,然后在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类文件中添加以下功能。别忘了导入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)")
        }
        })
    }
}

答案 2 :(得分:4)

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

如果您希望在100%Sprite Kit中构建应用程序,那么您将UIViewController视为包含Sprite Kit应用程序的shell。唯一一次你应该触摸这个是你需要做SpriteKit场景不应该做的事情,比如创建手势控制,什么不是。

但是,有多个视图控制器使用sprite kit元素。也许你正在制作一个商业应用程序,并决定加入一个小游戏。

IMO在网页设计方面考虑它的最佳方式是将您的View控制器视为您的HTML页面,并将您的场景视为您嵌入网站的flash / silverlight / unity / etc游戏玩家。有时候你希望那个播放器是全屏的,有时你不想要它,它归结为应用程序的设计。在全屏时,我们不需要任何其他组件,因此玩家可以完成所有工作。但是如果我们在页面上附上如何引导链接怎么办呢。我们不希望在游戏中使用它,我们希望它在它之外。然后,此链接将打开一个与旧页面无关的新页面,并且对游戏玩家组件没有用处。

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

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

答案 3 :(得分:0)

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