I have created a game similar to Flappy Bird. I have set up a function so that when the hero dies a restartScene is called. When touched this restarts the game so the user can continue to play.
My question is, is it possible to make it so there is a 2-3 seconds delay before the user can click restart?
func restartScene(){
self.removeAllChildren()
self.removeAllActions()
died = false
gameStarted = false
score = 0
createScene()
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if gameStarted == false{
gameStarted = true
for touch in touches{
let location = touch.location(in: self)
if died == true{
restartScene()
}
}
}
Use an SKAction
at the end of your createButton to perform a delay:
Scenario 1, you are using SKScene
to handle all touch events (this is what you have to be doing since restartButton is an SKSpriteNode
):
let enable = SKAction.run({[unowned self] in self.restartButton.isUserInteractionEnabled = false})
restartButton.isUserInteractionEnabled = true //This actually disables the button because the touch handler will not be called by scene, but instead the individual button.
//The individual button will have no touch code associated with it, so nothing will happen
restartButton.run(SKAction.sequence([SKAction.wait(duration:2),enable]), withKey:"waitingToEnable")
Scenario 2, you are using restartButton as a custom class:
let enable = SKAction.run({[unowned self] in self.restartButton.isUserInteractionEnabled = true})
restartButton.isUserInteractionEnabled = false //This disables the button because the touch handler will not be called by individual button, and instead will go to whatever is touch enabled under it.
restartButton.run(SKAction.sequence([SKAction.wait(duration:2),enable]), withKey:"waitingToEnable")
In your particular case, here is how I would write it:
func createButton(){
restartButton = SKSpriteNode(imageNamed: "restart")
restartButton.position = CGPoint(x: self.frame.width / 2, y: self.frame.height / 2)
restartButton.zPosition = 10
restartButton.setScale(1.2)
restartButton.name = "Restart"
restartButton.setScale(1.5)
self.addChild(restartButton)
let enable = SKAction.run({[unowned self] in self.restartButton.isUserInteractionEnabled = false})
restartButton.isUserInteractionEnabled = true //This actually disables the button because the touch handler will not be called by scene, but instead the individual button.
//The individual button will have no touch code associated with it, so nothing will happen
let waitAndEnable = SKAction.sequence([SKAction.wait(duration:2),enable])
let fadeIn = SKAction.fadeIn(withDuration: 1.5)
let runConcurrently = SKAction.group([waitAndEnable,fadeIn])
restartButton.run(runConcurrently)
highScoreLabel.text = "High Score: \(UserDefaults().integer(forKey: "HIGHSCORE"))"
highScoreLabel.fontColor = UIColor.white
highScoreLabel.fontSize = 20
highScoreLabel.position = CGPoint(x: 80, y: 20)
highScoreLabel.zPosition = 6
livesLabel.position = CGPoint(x: frame.size.width / 5.4, y: 30)
livesLabel.text = "Lives: \(lives)"
livesLabel.zPosition = 5
livesLabel.fontSize = 20
livesLabel.fontColor = UIColor.black
self.addChild(livesLabel)
livesLabel.zPosition = 10
}
It looks like you are not handling the touchesBegan properly. You have it set up to where the user touches anywhere on the scene, the game will restart.
You need to target the specific node to ensure that this happens.
I have added the touchesBegan changes to meet your needs. You will have to name your game scene what is in the case statement to get this to work.
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches{
let location = touch.location(in: self)
let node = nodeAtPoint(location)
switch(node.name)
{
case "Restart":
if died = true{
restartScene()
}
case "GameScene": //maybe we want to make this a button?
gameStarted = true //who cares about a branch statement
default:()
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With