0

When using Xcode, I've faced the annoying problem, which is Xcode always crashes when I click .SKS files. I have raised questions here, and even in Apple developer forum, as well as searched for the solutions on the Internet... but it is hopeless.

Because I am making a game with many scenes, so if I can't use SpriteKit editor to interact with the scenes in an easy way, I want to know how can I interact with my scenes by coding their .swift files.

So the question is, for example, when I create a file "EndScene.sks", how can I create a "EndScene.swift", which links with my .sks file?

Thank you very much!

Tr Hoangtien
  • 41
  • 1
  • 9

2 Answers2

7

Create a new swift file and name it the same as your .sks file. Let's say you have a .sks file called MainMenu.sks. You'd create a swift file called MainMenu.swift. Inside that file, you'll want to create a Main Menu class that inherits from SKScene.

import SpriteKit

class MainMenu: SKScene {

}

Inside there is where you'll put all your code. The key is, as you said, linking this to the .sks file.

When you go to present your scene, you'll instantiate the class and associate it with the .sks file.

import UIKit
import SpriteKit

class GameViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        if let scene = MainMenu(fileNamed:"MainMenu") {
            let skView = self.view as! SKView
            // Some settings applied to the scene and view
            // ... code ...

            skView.presentScene(scene)
        }
    }
//... other code
}

Note the line let scene = MainMenu(fileNamed:"MainMenu"). That's where you are instantiating the class you created in MainMenu.swift. So, technically, MainMenu() is the .swift file and fileNamed: "MainMenu" is the .sks file. You can technically put any .sks file into the init call and it'll render that scene.

Imagine having a game with all the logic for a maze runner. You could build all the game logic in a class called MazeScene and just make a bunch of .sks files, each with a different maze. You could then so something like, MazeScene(fileNamed: "MazeOne") or MazeScene(fileNamed: "MazeThree").

For the documentation on this, SKScene inherits from SKNode so you'll find the documentation for init(fileNamed:) here

That should get you going.

Charles Caldwell
  • 16,649
  • 4
  • 40
  • 47
  • Sidenote: I also experience a lot of crashes while using the Scene Editor. It is nice for some mild design work but I find myself doing all the more detailed work in code. – Charles Caldwell May 23 '16 at 15:04
  • Why is it "override func viewDidLoad()" not "override func didMoveToView(view: SKView)" ? – Tr Hoangtien May 23 '16 at 15:09
  • That's the root view controller. Every SpriteKit game has at least one. If you were doing this inside a `SKScene` instance, you might do something like `self.view!.presentScene(scene, transition: transition)` where `scene` is the `let scene = MainMenu(fileNamed:"MainMenu")` – Charles Caldwell May 23 '16 at 15:13
  • Ah sorry for my previous silly question :P I got it! Besides linking the .swift file to .sks file, I still have to edit the GameViewController.swift file. Thank you very much!!! – Tr Hoangtien May 23 '16 at 15:16
  • Sorry, after I edited GameViewController.swift,all my two scenes (my game has only 2 scenes: GameScene.sks and EndScene.sks - the scene I have just created) appears at the same time. How can I make GameScene to run first? – Tr Hoangtien May 23 '16 at 15:40
  • Sorry, I should have clarified. In a game I'm working on, I have the Main Menu as the first scene. So, that's the only one I launch in the root view controller. I don't launch any others. In my `MainMenu.swift` file, that's where I instantiate the other scenes. So, if someone taps on my "Play" button, I use `self.view!.presentscene(.....` in order to launch it. – Charles Caldwell May 23 '16 at 16:04
  • Check out this answer for some good advice on launching scenes from within scenes: [http://stackoverflow.com/questions/24111935/how-to-transition-scenes-in-swift](http://stackoverflow.com/questions/24111935/how-to-transition-scenes-in-swift) – Charles Caldwell May 23 '16 at 16:05
  • Now, I have successfully made my EndScene launched from GameScene by putting this code in GameScene: self.view?.presentScene(SKScene(fileNamed: "EndScene")) However, when EndScene is launched, it is completely blank. I have tried many ways, and put many different content in EndScene.swift already. But it still appears as a blank scene when I run the application. – Tr Hoangtien May 23 '16 at 16:46
  • Try `self.view?.presentScene(EndScene(fileNamed: "EndScene"))`. Using `SKScene()` will just create a brand new blank SKScene whereas using `EndScene()` will create a new instance of your End Scene class where all your code resides. – Charles Caldwell May 23 '16 at 16:57
  • OMG!!! Finally!!! You are my Savior! I just can't say thank enough to you. All my problems are solved! – Tr Hoangtien May 23 '16 at 17:04
  • No problem! Glad I could help. – Charles Caldwell May 23 '16 at 17:05
1

So instead of commenting I have to wander because StackOverflow won't let me comment, how much of this is the same in swift 3? And when you were doing this in the UIViewController you said

if let scene = MainMenu(fileNamed:"MainMenu") {
        let skView = self.view as! SKView
        // Some settings applied to the scene and view
        // ... code ...

        skView.presentScene(scene)
    }

What do you mean by

// ... code ...

Do we put all of the code we would put in the SKScene class in there instead? I thought the whole point was to have a separate SKScene class. And when I try it like that the SKScene class I have doesn't load. Thanks for any clarification and sorry I have to answer instead of comment. It's pretty stupid that you need 50 reputation to leave a comment I don't see any point in that. Anyway, Thanks!