I would like to create a main menu for my game in swift.
I am using the following code:
import SpriteKit
class menuScene: SKScene {
//Adding Start Button
let startButton = SKSpriteNode(imageNamed: "playButton")
override func didMove(to view: SKView) {
//Temporary Background
backgroundColor = SKColor.darkGray
//Start Button
startButton.position = CGPoint(x: size.width / 2, y: size.height / 2)
addChild(startButton)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches {
let location = touch.location(in: self); //Finding location of touch
if atPoint(location) == startButton {
if let scene = GameScene(fileNamed: "GameScene") {
scene.scaleMode = .aspectFill
view!.presentScene(scene, transition: SKTransition.doorsOpenVertical(withDuration: 1))
}
}
}
}
}
When I run this however, My app crashes and highlights if atPoint(location) == startButton {. with "Thread 1, Breakpoint 1.1"
Im not entirely sure what this is but I hope someone can help. Thanks!
Custom SKViews
Let's say, like this M.W.E., you want a menu, a difficulty, and a game scene.
Then you can make a series of custom SKViews
to transition between.
GameViewController
This code loads the menuScene:
override func viewDidLoad() {
super.viewDidLoad()
let menuScene = MenuScene(size: view.bounds.size)
let skView = view as! SKView
skView.showsFPS = true
skView.showsNodeCount = true
skView.ignoresSiblingOrder = true
menuScene.scaleMode = .resizeFill
skView.presentScene(menuScene)
}
MenuScene
class MenuScene: SKScene {
let playButton = SKLabelNode()
override init(size: CGSize) {
super.init(size: size)
backgroundColor = SKColor.white
playButton.fontColor = SKColor.black
playButton.text = "play"
playButton.position = CGPoint(x: size.width / 2, y: size.height / 2)
addChild(playButton)
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
let touchLocation = touch!.location(in: self)
if playButton.contains(touchLocation) {
let reveal = SKTransition.doorsOpenVertical(withDuration: 0.5)
let difficultyScene = DifficultyScene(size: self.size)
self.view?.presentScene(difficultyScene, transition: reveal)
}
}
}
DifficultyScene
class DifficultyScene: SKScene {
let easyButton = SKLabelNode()
let hardButton = SKLabelNode()
let menuButton = SKLabelNode()
override init(size: CGSize) {
super.init(size: size)
backgroundColor = SKColor.white
easyButton.fontColor = SKColor.black
easyButton.text = "easy"
hardButton.fontColor = SKColor.black
hardButton.text = "hard"
menuButton.fontColor = SKColor.black
menuButton.text = "menu"
easyButton.position = CGPoint(x: size.width / 2, y: size.height / 2)
hardButton.position = CGPoint(x: size.width / 2, y: size.height / 2 - easyButton.fontSize * 2)
menuButton.position = CGPoint(x: size.width / 4 * 3, y: size.height / 4)
addChild(easyButton)
addChild(hardButton)
addChild(menuButton)
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
let touchLocation = touch!.location(in: self)
if easyButton.contains(touchLocation) {
let reveal = SKTransition.doorsOpenVertical(withDuration: 0.5)
let gameScene = GameScene(size: self.size, difficulty: easyButton.text!)
self.view?.presentScene(gameScene, transition: reveal)
}
if hardButton.contains(touchLocation) {
let reveal = SKTransition.doorsOpenVertical(withDuration: 0.5)
let gameScene = GameScene(size: self.size, difficulty: hardButton.text!)
self.view?.presentScene(gameScene, transition: reveal)
}
if menuButton.contains(touchLocation){
let reveal = SKTransition.doorsOpenVertical(withDuration: 0.5)
let menuScene = MenuScene(size: self.size)
self.view?.presentScene(menuScene, transition: reveal)
}
}
}
GameScene
add this to your GameScene
:
init(size: CGSize, difficulty: String) {
super.init(size: size)
gameDifficulty = difficulty
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
Storyboards
Alternatively, you can use Storyboards. In the M.W.E. for another S.O. question they have a basic "menu" set up.
In your case, what you would do is:
- go to Main.storyboard.
- on the right-hand tool bar, find view controller
- drag view-controller into Main.storyboard
- click on the new view-controller
- click - on the right-hand tool bar - the identity inspector (looks like a business card)
- change Class to GameViewController
- click on view within the hierarchy on the left (under the new view controller)
- click the identity inspector
- change class to SKView
- click on the original view controller
- click on the identity inspector
- change class to UIViewController
- click on the view within the original UIViewController
- click on identity inspector
- change class to UIView
- find button at the bottom of the right-hand side tool bar
- drag it onto the first view
- right click drag from the button to the second view
- on the pop-up menu, under action segue, click show
- right click drag from the button up, add horizontally center constraints
- right click drag from the button to the right, add vertically center constraints
Images