1

I'm developing a game in Swift using the SpriteKit framework. In this app, I have GameScene.sks where my UI is presented. Within that .sks file there is an SKReferenceNode for the bottom-menu. The bottom-menu is going to change it's height if the user is running the game from an iPhone X.

However, I have some trouble getting to that point. I made the menu a SKReferenceNode because it's used in multiple scenes - so if I change the menu, it will change in all of the scenes (GameScene.sks, GameScene1.sks, GameScene2.sks and so on.. )

What would be the best way to approach this? I'm sorry if this is an obvious question, but I've been starring myself blind at this one.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
theloneswiftman
  • 188
  • 1
  • 4
  • 17
  • You need to change the height based in the code behind of the sks file that the SKReferenceNode uses. The height difference is negligible between the X and the other 16:9 devices, is it worth the effort? – Knight0fDragon Jan 19 '18 at 18:31

1 Answers1

1

you are doing fine, using menu as an SKReferenceNode is what I would do as well. However you don't need to alter it from the GameViewController to achieve the results you want.

What I do in the situation where I need the appearance of an RefNode to be dependant on some variables I don't load the appearance in the required init

normally inside of the RefNode class I do this

class SomeObject: SKSpriteNode {
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        setup()
    }

    func setup() {
        //setup objects in here
    }
}

but instead when i need to alter the presentation i comment out the setup call in the required init

and then call setup from the initialization code in my GameScene

class SomeObject: SKSpriteNode {
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)    
        //setup()
    }

    func setup(height: CGFloat) {

        //setup objects in here
        if let background = self.childNode(withName: "//background") as? SKSpriteNode {
            self. background = background
            background.size.height = height
        }
    }
}

then in GameScene

func createSomeObject() {

    if let someObjectNode = self.childNode(withName: "//someObjectNode") as? SKReferenceNode {

        someObject = someObjectNode(withName: "//someObjectNode") as? SomeObject

        //you can figure out this multiple ways
        if isIpad {
            height = 50
        }
        else if isIphoneX {
            height = 250
        }
        someObject.setup(height: height)
    }
}
Ron Myschuk
  • 6,011
  • 2
  • 20
  • 32
  • Thank you many times for the solution, Ron! That's great! However, as I read your answer then I have to add the "func createSomeObject()" method to all of my scenes - is that correct, or am I missing something? :) – theloneswiftman Jan 19 '18 at 20:51
  • 1
    yes, at some point in your scene you are probably going to want to find that object in your scene and put it into a local variable so that you can access that object from anywhere in your scene. for example. if it was a GameHUD that you created in an SKReferenceNode you would put that object in a local variable gameHUD so that you could access its properties from the scene, like `gameHUD.score = 50` that's all the createSomeObject func is doing – Ron Myschuk Jan 19 '18 at 20:57
  • @user2026507 let me know if this works for you, and if it does please mark it as correct to help others that might have these issues – Ron Myschuk Jan 19 '18 at 21:10
  • Sorry for the late reply. Works like a charm. Thank you, Ron! – theloneswiftman Feb 05 '18 at 11:45