1

I am trying to work on a new game project where I will include multiple levels. I was reading this question (Sprite Kit - Defining the variables for multiple scenes) about the best way to do multiples scenes with as little duplicate code as possible. The answer of course is subclassing.

So say I create my "baseScene" which is a subclass of SKScene. Here, as suggested, I should put all the relevant code (player, objects, collisions bit masks, touches began functions etc) that will be shared across all subclass level scenes. I used the usual did moveToView function in baseScene to add the content and it works perfect across multiple scenes (level1Scene, level2Scene etc) that are all subclasses of baseScene. Same goes for touches began functions and so on, so no problem with that.

My issue now however is that in my "level1Scene" I cannot for the life of me figure out how to add stuff that's on top of what is in baseScene such as level 1 enemies, obstacles or backgrounds. I cannot use didMoveToView since it's an override function and will remove everything I have added in my baseScene superclass.

I would appreciate any support and my apologises if this is a basic and probably stupid question but I am fairly new to swift, especially scene subclassing.

Community
  • 1
  • 1
crashoverride777
  • 10,581
  • 2
  • 32
  • 56

1 Answers1

3

You can override functions of baseScene in level1Scene, you just need to make sure you call the super version of the method. Here are a few examples, in your level1Scene class:

override func didMoveToView(view: SKView) {
    super.didMoveToView(view) // Calls `didMoveToView` of `baseScene`.

    // Additional setup needed for `level1Scene`...
} 

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    super.touchesBegan(touches, withEvent: event) // Calls `touchesBegan` of `baseScene`.

    // Additional stuff you want to do in `level1Scene`...
}
ABakerSmith
  • 22,759
  • 9
  • 68
  • 78
  • Hey I will no problem, sorry I am brand new to this website, still trying to learn the layout. If you can help me with one more issue I would be so happy. Say in my "base scene" i have my collision detection ( let groundCategory : UInt32 = 0x1 << 0 etc) and it works great for the subclasses. However I also got another scene "player" which is a subclass of SKSpriteNode. Since I can't make this a subclass of BaseScene I am struggling to get the collision detection to recognise in this scene. What would be the right way to make this PlayerScene also recognise the collision. You are a star – crashoverride777 May 29 '15 at 09:55
  • I'm a bit confused with your use of the word 'scene'; a scene is an `SKScene` subclass, not a subclass of an `SKSpriteNode`. It sounds to me like this might be something to ask in another question :) – ABakerSmith May 29 '15 at 14:01
  • Sorry, if I wasn't clear. In my "base scene" (subclass of SKScene) I have my collision detection categories. In my "level scenes" I can access them no problem (e.g. for didBeginContact) because all "levelScenes" are subclasses of "baseScene". However I also got some SKSpriteNode classes where I store SpriteNodeProperties. I cannot access the collisionCategories I stored in "baseScene" in those SKSpriteNode classes. So basically is there a way I can access the properties stored in "baseScene" in scenes that are not subclasses of it (i.e my SpriteNodeClasses). – crashoverride777 May 29 '15 at 14:55
  • Definitely something for another question, then you can post your code and I can get a better idea of the structure you've setup. – ABakerSmith May 29 '15 at 17:46
  • Incase you are interested I figured out my second question myself. Basically what I was looking for was a way to reference properties in "baseScene" in other scenes/classes which are not subclasses of "baseScene". So for example in my player "SpriteNodeClass" at the top level I wrote "let baseScene = BaseScene()", which gives me the reference to my BaseScene. Than I was able to access the collision detection values by writing for example ".... = self.baseScene.playerCategory". Super easy actually. Once again thanks – crashoverride777 May 30 '15 at 19:28
  • You could do that, one problem is you're gonna end up with an instance of `BaseScene` for every instance of your `SKSpriteNode` subclass, and an `SKScene` isn't the most lightweight object. Instead, you could declare the collision categories of `BaseScene` as `static`, then you could reference them from your `SKSpriteNode` subclass like: `BaseScene.collisionCategory1` (This avoids needing to create a new `BaseScene`) :) – ABakerSmith May 30 '15 at 19:31
  • I appreciate your reply. I didn't know that with this way I am creating multiple BaseScenes. When you say "static" you mean something like "static let playerCategory = ...."? I am slightly confused what you mean. – crashoverride777 May 30 '15 at 22:18
  • You will be creating multiple versions of `BaseScene` if you've got a `baseScene` variable in your subclass of `SKSpriteNode`. If the `BaseScene` is at the top level of the file you'll just have one extra. (I'm assuming you're not presenting this `BaseScene`). And exactly, like `static let playerCategory = ....` – ABakerSmith May 30 '15 at 22:20
  • ok, the problem I have now is that when I change to static let (before I just had let) my categories won't get recognised anymore. I don't want to trouble you too much, sry, but can you explain one more time the easiest way for me to reference my baseScene in my SKSpriteNode class without creating multiple instance like you said. Thanks – crashoverride777 May 30 '15 at 22:33
  • Wherever you've referenced the categories you'll now need to prefix them with `BaseScene`. For example, say you had `static let playerCategory = ...` in `BaseScene`. You'd need to reference it like so: `BaseScene.playerCategory`. Does that help? – ABakerSmith May 30 '15 at 22:35
  • It does thank you. However when I put them on static I cannot use them in my subclasses according to some articles I read, which could cause me some problems later on with my levelScenes. Correct me if I am wrong with this. Its not that problematic really, I could just copy the collisionCategories i need and put them straight into the SKSpriteNodeClass. I would just prefer to have all Categories in baseScene. Is there a way for me to reference without using static. I promise I won't ask anymore questions. Thanks for your continued help. – crashoverride777 May 30 '15 at 22:43
  • 1
    Never Mind, I had to change the collision detection to be a struct", like most tutorials do. As soon as I changed it to "struct PhysicsCategory {...." it worked with "static let" and I can call it in my SKSpriteNode scene like you said with "BaseScene.PhysicsCategory.player or BaseScene.PhysicsCategory.enemy". If I don't use a struct it won't recognise the categories with "static let", only "let". Don't know why that is but it works fine with a struct and I can reference. Guess I got to read some more about static, structs, classReferencing and subclassing. Thanks again your awesome. – crashoverride777 May 30 '15 at 23:13
  • I'm glad I could help and that it's all working for you now. Good luck with your project! :) – ABakerSmith May 30 '15 at 23:16