Difference between GameViewController and SKScenes
Asked Answered
A

4

7

I've been developing a game using SpriteKit and Swift but I seem to be having trouble determining what the real differences are between the GameViewController and any one of my SKScenes. I'm trying to understand the differences because I want to implement a GameCenter or local leaderboard into my game but in all the tutorials I find (like this one:Game Center Leaderboards! (Swift 2 in Xcode) ) they have all the logic in GameViewController as they are working with single view apps. I'm having trouble understanding the relation when I read the docs, so any help would be great. Ultimately, I want to be able to display and push data to and from GameCenter in one of my scenes such as GameOverScene. Thanks for any help!

Austenite answered 25/8, 2016 at 18:0 Comment(1)
This is actually a very good question that a lot of people seem to not fully grasp, you should actually request this at SO:DocumentationAweather
P
8

Here is some good info to start with:

Diagram of what happens each frame in SK:

enter image description here


So you see, the SKScene is the class with all of the fun stuff like Nodes and Actions, and is where everything (important to you) happens. You can generate these scenes through the Editor, but then you probably need to make a new .swift file to go with it (as each scene can have its own logic).

The editor is just a 'shortcut' to initializing a bunch of stuff, and honestly, you can make complete games with little code (but you very quickly find out that you want more)

So in this code, where you declare GameScene or PauseScreen (which are basically just class declarations, that inherit from SKScene), you quickly find this line talking about something that ISNT a scene:

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


We find this SKView declaration in the GameViewController file, (which is just a class), notice that it's the same as the regular iOS apps mostly, as it inherits 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)
    }

Again, that method is declared in GameViewController.swift, which is basically just this: class GameViewController: UIViewController


So how does all of this relate to iOS apps and SpriteKit? Well, they are all mashed on top of each other:

IOS app anatomy:

anatomy

Basically, from right to left, you have the Window, which is (correct me if wrong) the AppDelegate, then the ViewController, then your View, which has all of the cool stuff in it (Storyboards sit inside of the View, just as SKScenes sit inside of the View.... Labels, Nodes, or Buttons, all sit inside of their respective classes ((the view)))

It's all a big sandwich of inheritance.


Check out the Apple websites for more info.

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

Basically, everything is an Class inherited from a class inherited from a class and so on, so on... It can get messy. You can also see these inheritances in Xcode by CMD+clicking on them, which will jump you to the source file.

Goodluck with your studies and adventures in SpriteKit :)

Pyro answered 25/8, 2016 at 19:52 Comment(8)
You are missing the point of the question, you explain scenes and view, but you do not explain the difference of a view controller and a sceneAweather
@Knight0fDragon, I've been working on some edits because I saw I left out some info. Please check my update and let me know what you think.Pyro
I think the OP is going to need to comment to improve this answer, it is tough to tell what he is exactly looking for here.Aweather
@knight0fDragon I've been helping him with his other files earlier today, where he explained it in a bit more detail: #39149904 In that, i show specifically how the Controller interacts with the Scenes. I don't feel as if I'm strong enough in this material to give elaborate answers, because I'm still new myself. I was trying to give resources (even though I'm a tutor IRL) I didn't want to explain, then find out I made a big mistake.Pyro
Well then it looks like he really needs to start hitting some tutorials, to learn the actual step by steps of how things work in Sprite KitAweather
:D he's been watching YT and reading. Apple is to blame for making this stuff so damn easy to get into xD But yeah, "studying" was included in my answer ;) Thank you for your feedbackPyro
Unfortunately YT is the worst place to go, I have yet to see a good video that actually can help a person, they are all do this do this do this, but they never explain the "Why" you do that.Aweather
Some people learn from doing, others need to have stuff explained. It comes down to an individuals level of metacognition (how well they can find information on learning, assessing their learning, etc). But agreed, the "why" of things is typically nowhere to be found outside of a college campus (and even then, many intro classes don't bother with critical thinking)Pyro
I
5

You should only have a single GameViewController in your game. SKScenes are the scenes that the game transitions in between an to.

For example, the home menu screen? That's an SKScene. The main gameplay? That's an SKScene. The gameover screen? That's an SKScene.

The GameViewController initializes the entire view that the game will be maintained in, so the view. The SKScenes are just scenes that are placed on top of the view. You should be looking at a tutorial that uses SKScenes.

Here's how to make game center work as of the latest Swift 2.2.

Add this function anywhere inside the GameViewController class, and then just call it right after 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))
        }
    }
}

Add the following functions in your SKScene class file. Don't forget to import GameKit. Just call showLeader() whenever you want the leaderboard to be displayed.

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)
}

And this is a sample I have of how the score is saved to game center.

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)")
        }
        })
    }
}
Islet answered 25/8, 2016 at 18:32 Comment(5)
What should self refer to in the line gKGCViewController.gameCenterDelegate = self if this method is within my GameOverScene? I get the error Cannot assign value of type GameOverScene to type GKGameCenterControllerDelegate? ?Austenite
add GKGameCenterControllerProtocol to the SKScene class. Make sure that function showLeaderboard() is inside the SKScene class since self refers to the instance of the class object.Islet
@Sam, I put the entirety of the code on the other question you started. It includes the GK thing too :PPyro
@jozemiteApps Thanks a lot I just got that working now, but the score isnt being updated-- couldnt I call saveHighScore in the viewdidload of the scene?? I also get this error: Attempting to load the view of a view controller while it is deallocating is not allowed and may result in undefined behavior (<UIAlertController: 0x1489d2190>)Austenite
No, why would you call it in the viewDidLoad when the player hasn't even played yet? The point of saveHighScore is to save the score when the user gets a new high score, which for me is called in the game over function. As for the error, I always get that but game center still works 100%. It means the view is trying to unload itself while it's loading. Sounds like it's a protocol function that I never bothered to implement. The function gameCenterViewControllerDidFinish() is a protocol function called by GameKit itself, not me. Could be one of those functions that aren't required to add.Islet
A
4

It all depends about how you are designing your app, and what technologies you want to use.

If you are looking to build an app in 100% Sprite Kit, then you treat your UIViewController as a shell that holds your Sprite Kit app. The only time you should be touching this is when you need to do things that the SpriteKit scene shouldn't be doing, like creating gesture controls and what not.

However, there are uses to having multiple view controllers with sprite kit elements. Perhaps you are making a business application, and decide to include a little game to go with it.

IMO the best way to think about it in terms of web design is think of your View controller as your HTML page, and think of your Scene as your flash/silverlight/unity/etc game player that you embed in the website. Sometimes you want that player to be full screen, some times you do not, it comes down to the design of the application. When in full screen, we do not need any other components, so the player can do all the work. But what if we attach a how to guide link on the page. We wouldn't want this in game, we want this outside of it. This link will then open up a new page, not associated with the old page, and has no use for the game player components.

Now for your situation with Game Center, it gets more complicated. Game Center was built before Sprite Kit came to existence, so all of its functionality is built on UIKit. But Game Center also allows for customization, so you do not have to use the UIKit features of it. Of course, you will have to do all of the work then in displaying the information inside of your scene with Sprite Kit objects.

To make life easiest for you, you would include all of the built in code needed into your View Controller, then what you do is create a delegate that the scene knows about, and assign your view controller to this delegate. Now Game Scene can access any element of that view controller that you allow, like presenting leader boards or passing up leader boards. Check out this tutorial in its entirety, it will help you learn all you will need to achieve what you want. https://www.raywenderlich.com/115300/swift-2-tutorial-part-3-tuples-protocols-delegates-and-table-views

Aweather answered 25/8, 2016 at 19:53 Comment(0)
F
0

In MVC the controller acts as a coordinator, a bit like the conductor in an orchestra. My preference is that scenes just do the one thing they were designed for i.e. implement game play. When a scene is completed, the final task is to notify the controller (using delegate pattern) that the scene is complete. It is then up to the controller to decide what happens next i.e. transition to next scene or game over.

Fugato answered 26/8, 2016 at 1:5 Comment(7)
actually the controller should not be telling the scene what to do, The conductor is the View Controller, the View are the musicians in the orchestra and your scene is the instrument. The View controller should tell the view a transition is happening, and the view should tell the scene that it is changing, same concept as what you are trying to get at, just more elaborated on.Aweather
I like the idea that the scene does only one thing and doesn't know anything about the bigger picture of the game. That's the S in SOLID (single responsibility) to use a software analogy. It's the job of the GameViewController to present the scenes in the correct sequence and to restart where the user left off etc.Fugato
And it shouldn't, I am just saying MVC does not work 100% in its simple format due to the SKView having to be an intermediateAweather
@JozemiteApps, that is not true, it is a pattern that actually works well with MMOs (You tell the server what to do (the model), the server shows you what you should be seeing), would work fine in Sprite kitAweather
@JozemiteApps, I find the integration between SpriteKit and UIKit to be so good, that I don't see any difference between games and other apps. My preference is to have non game components like start screens, settings screens and the Leaderboard referred to by the OP implemented in UIKit.Fugato
@Aweather I meant the MVC pattern isn't generally considered for SpriteKit games. Just Google it and you will see people say that it can't really be integrated like a non-game app, at least not in the traditional sense. I do know that you can apply the MVC pattern in some way because I wrote an article on how to do it on my website with SpriteKit.Islet
We can go into a year long debate on this kind of stuff, but it is not safe to assume it will not work because of the technology and go around spreading it to those who cannot think for themselves. You need to always ask yourself, does it make sense to use a particular pattern for a particular application, then apply the technology, not the other way aroundAweather

© 2022 - 2024 — McMap. All rights reserved.