R. Khaira R. Khaira - 7 days ago 5
Swift Question

Adding button to GameScene.swift programatically and transitioning scenes when pressed

I have been working forever trying to implement a way to add a button and when pressed the scene transitions to my second view. I have read other posts but have had ZERO luck for something in Swift 3. I'm really confused and have tried but failed many times. Hope you can help! Thanks!

Swift 3 in SpriteKit.

Answer

What do you mean transition to a new view?. When making SpriteKit games we tend to transition between SKScenes and not views. So do not try to create different views or viewControllers for each scene, just transition between SKScenes directly.

In regards to buttons, there is plenty tutorials available. You basically create a SKSpriteNode as a button and look for it in touchesBegan and do something when its pressed.

This is a simple example here

https://nathandemick.com/2014/09/buttons-sprite-kit-using-swift/

Essential you can create a button subclass similar to this.

class Button: SKNode {
      let defaultButton: SKSpriteNode
      let activeButton: SKSpriteNode
      var action: () -> ()

      init(defaultButtonImage: String, activeButtonImage: String, buttonAction: @escaping () -> ()) {
           defaultButton = SKSpriteNode(imageNamed: defaultButtonImage)
           activeButton = SKSpriteNode(imageNamed: activeButtonImage)
           activeButton.isHidden = true
           action = buttonAction

           super.init()

           isUserInteractionEnabled = true
           addChild(defaultButton)
           addChild(activeButton)
     }

     required init(coder aDecoder: NSCoder) {
           fatalError("init(coder:) has not been implemented")
     }

     override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        activeButton.isHidden = false
        defaultButton.isHidden = true
     }

     override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch in touches {
             let location = touch.location(in: self)

             if defaultButton.contains(location) {
                  activeButton.isHidden = false
                  defaultButton.isHidden = true
             } else {
                   activeButton.isHidden = true
                   defaultButton.isHidden = false
             } 
        }
     }

     override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
          for touch in touches {
             let location = touch.location(in: self)

             if defaultButton.contains(location) {
                 action()
             }

             activeButton.isHidden = true
             defaultButton.isHidden = false
         }
    }
}

and than in your relevant SKScene add your buttons

 let playButton = Button(defaultButtonImage: "button", activeButtonImage: "button_active", buttonAction: loadGameScene)
 playButton.position = CGPoint(x: frame.midX, y: frame.midY)
 addChild(playButton)

and create the method that gets called when the button is pressed. In this example you transition to a new SKScene.

 func loadGameScene() {
    let scene = GameScene(...)
    let transition = SKTransition....
    scene.scaleMode = .aspectFill
    view?.presentScene(scene, transition: transition)
 }

You can also check out Apples sample game DemoBots for another button class example using protocols.

Hope this helps

Comments