Search code examples
swiftxcodebuttonlabelskspritenode

Created Buttons appear in other scenes within the Game


// Button class

class Button: UIButton {

override init(frame: CGRect){
    super.init(frame: frame)
  setup()
}

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

func setup(){
    backgroundColor = #colorLiteral(red: 0.1215686277, green: 0.01176470611, blue: 0.4235294163, alpha: 1)
    layer.cornerRadius = 12
    layer.masksToBounds = false
    translatesAutoresizingMaskIntoConstraints = false
}

}

// The Class where button object is being created

struct Question { var Question : String! var Answers : [String]! var AnswerNumber : Int! }

class LevelOne: SKScene {

var button = Button()

var buttons = [Button]()
let Question_met = UILabel(frame: CGRect(x: 0.3, y: 0.3, width: 40, height: 21))

var Questions = [Question]()

var QNumber = Int()

var buttonNames = [""]

var AnsNumber = Int()

let selectors:[Selector] = [#selector(handleButton1), #selector(handleButton2), #selector(handleButton3),#selector(handleButton4)]

override func didMove(to view: SKView) {
    
    let background = SKSpriteNode(imageNamed: "background")
    background.position = CGPoint(x: self.size.width/2, y: self.size.height/2)
    background.zPosition = 0
    self.addChild(background)
    
    questionFunction()
    
    buttonFuction()
     
    pickQuestion()
    
}

@objc func questionFunction(){
    
    Questions = [Question(Question: "What is a BMW ?", Answers: ["Bat","Cat","Vehicle","Pat"], AnswerNumber: 2),
    Question(Question: "What is a Boeing ?", Answers: ["Bat","Aircraft","Cat","Pat"], AnswerNumber: 1),
    Question(Question: "What is a Ant ?", Answers: ["Insect","Cat","Insect","Nate"], AnswerNumber: 2),
    Question(Question: "What is a Apple ?", Answers: ["Fruit","Cat","bat","Pat"], AnswerNumber: 0),
    Question(Question: "Where is london ?", Answers: ["UK","USA","France","Germany"], AnswerNumber: 0),
    Question(Question: "Where is New York ?", Answers: ["Canada","USA","France","Germany"], AnswerNumber: 2),
    Question(Question: "where is Berlin ?", Answers: ["UK","USA","Italy","Germany "], AnswerNumber: 3),
    Question(Question: "Where is Toronto ?", Answers: ["India","Africa","Canada","Norway"], AnswerNumber: 2),
    Question(Question: "Where is Rome ?", Answers: ["Japan","China","Italy","Ireland"], AnswerNumber: 2),
    Question(Question: "where is Chennai ?", Answers: ["India","Brazil","Swiss","Germany"], AnswerNumber: 0),]
    
    Question_met.frame = CGRect(x: 330, y: 70, width: 200, height: 21)
    Question_met.backgroundColor = UIColor.orange
    Question_met.textColor = UIColor.white
    Question_met.textAlignment = NSTextAlignment.center
    Question_met.text = "What caused Global Warming ?"
    self.view?.addSubview(Question_met)
    
}

@objc func buttonFuction(){
    
    let stacView = UIStackView()
    stacView.spacing = 12
    stacView.distribution = .fillEqually
    stacView.axis = .horizontal
    stacView.translatesAutoresizingMaskIntoConstraints = false
    view!.addSubview(stacView)
    
    buttonNames = ["One","Two","Three","Four"]
    
    for i in 0..<4{
        
        button = Button()
        button.setTitle(buttonNames[i], for: .normal)
        stacView.addArrangedSubview(button)
        buttons.append(button)
        button.addTarget(self, action: selectors[i], for: .touchUpInside)
        
    }

    NSLayoutConstraint.activate([stacView.centerXAnchor.constraint(equalTo: view!.centerXAnchor),stacView.centerYAnchor.constraint(equalTo: view!.centerYAnchor),stacView.widthAnchor.constraint(equalToConstant: 350),stacView.heightAnchor.constraint(equalToConstant:70)])
    
}

@objc func pickQuestion(){
    
    if Questions.count > 0{
        QNumber = 0
        Question_met.text = Questions[QNumber].Question
        
        AnsNumber = Questions[QNumber].AnswerNumber
        
        for i in 0..<buttons.count{
            buttons[i].setTitle(Questions[QNumber].Answers[i], for: .normal)
        }
        Questions.remove(at: QNumber)
    }
    else {
        print("Done!")
        
        let sceneToMoveTo = Instructions(size: self.size)
        sceneToMoveTo.scaleMode = self.scaleMode
        let myTransition = SKTransition.fade(withDuration: 0.5)
        self.view!.presentScene(sceneToMoveTo, transition: myTransition)
        
    }
}

@objc func handleButton1() {
    
    if AnsNumber == 0 {
        pickQuestion()
        print("Correct!")
    }
    
    else {
        print("You are Wrong!!!")
    }
}

@objc func handleButton2(){
    
    if AnsNumber == 1 {
        pickQuestion()
        print("Correct!")
    }
    
    else {
        print("You are Wrong!!!")
    }
    
}

@objc func handleButton3(){
    
    if AnsNumber == 2 {
        pickQuestion()
        print("Correct!")
    }
    
    else {
        print("You are Wrong!!!")
        
    }
    
}

@objc func handleButton4(){
    
    if AnsNumber == 3 {
        pickQuestion()
        print("Correct!")
    }
    
    else {
        print("You are Wrong!!!")
    }
    
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {


}

}

I currently developing a game, which contains various levels and menu scenes. The current level created a question label and answer buttons and even after the level is complete and you navigate to another scene the buttons and questions remain on the scene no matter which scene you navigate too.

I was hoping to get a solution to only have the buttons and label to appear on the designated scene and don't appear in other scenes unless stated.

Thank you in advance.


Solution

  • I don't think you understand the ownership model here. The ViewController owns its view. The view owns the SKView and the SKView owns the SKScene. There is a back pointer from the SKScene to its SKView, and you are using that to add a UIKit StakcView to the Scene's parent view. Since UIKit sits on top of the SKScene, your button is always visible. The correct architecture here is that the view should add and manage its own subviews. Whenever it loads a new SKScene it should determine what UI that scene needs and then hide any UI that should no be shown. You can do this by just setting .isHidden on the relevant views.