Search code examples
iosswiftswift3sprite-kitskscene

Create a main menu for game in swift using spritekit swift


I am new to swift, and have an SKScene in which I have created a game. I can not seem to figure out however, how to build the menu. If seen both solutions to create either another view controller or another SKScene but they were all quite confusing and complex. I am open to use either of these methods or any other, does anyone have any tricks to tackle this problem. Some code would be helpful. Thanks for the help.


Solution

  • There are many ways to obtain a menu in Sprite-Kit.

    Usually people draw some SKLabelNode, or SKSpriteNode to build menu voices or make a specific SKNode that build this kind of structure.

    But I want to follow a suggestion on comments about StackView. We know StackView is an UIKit element that:

    Provides a streamlined interface for laying out a collection of views in either a column or a row.

    So , we can build a vertical StackView that contains all the menu voices (P.S. the code below show a simple collection of labels, you can customize your StackView views as you wish):

    import SpriteKit
    import UIKit
    protocol StackViewDelegate: class {
        func didTapOnView(at index: Int)
    }
    class GameMenuView: UIStackView {
        weak var delegate: StackViewDelegate?
        override init(frame: CGRect) {
            super.init(frame: frame)
            self.axis = .vertical
            self.distribution = .fillEqually
            self.alignment = .fill
            self.spacing = 5
            self.isUserInteractionEnabled = true
            //set up a label
            for i in 1...5 {
                let label = UILabel()
                label.text = "Menu voice \(i)"
                label.textColor = UIColor.white
                label.backgroundColor = UIColor.blue
                label.textAlignment = .center
                label.tag = i
                self.addArrangedSubview(label)
            }
            configureTapGestures()
        }
        required init(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        private func configureTapGestures() {
            arrangedSubviews.forEach { view in
                view.isUserInteractionEnabled = true
                let tapGesture = UITapGestureRecognizer(target: self, action: #selector(didTapOnView))
                view.addGestureRecognizer(tapGesture)
            }
        }
        func didTapOnView(_ gestureRecognizer: UIGestureRecognizer) {
            if let index = arrangedSubviews.index(of: gestureRecognizer.view!) {
                delegate?.didTapOnView(at: index)
            }
        }
    }
    class GameScene: SKScene, StackViewDelegate {
        var gameMenuView = GameMenuView()
        private var label : SKLabelNode?
        override func didMove(to view: SKView) {
            self.label = self.childNode(withName: "//helloLabel") as? SKLabelNode
            if let label = self.label {
                label.alpha = 0.0
                label.run(SKAction.fadeIn(withDuration: 2.0))
            }
            // Menu setup with stackView
            gameMenuView.frame=CGRect(x:20,y:50,width:280,height:200)
            view.addSubview(gameMenuView)
            gameMenuView.delegate = self
        }
        func didTapOnView(at index: Int) {
            switch index {
            case 0: print("tapped voice 1")
            case 1: print("tapped voice 2")
            case 2: print("tapped voice 3")
            case 3: print("tapped voice 4")
            case 4: print("tapped voice 5")
            default:break
            }
        }
    }
    

    Output:

    enter image description here

    enter image description here