Trying to make my restart button stay idle for 2 - 3 seconds

I created a game similar to Flappy Bird. I created a function, so when the hero dies, restartScene is called. When touched, this restarts the game so that the user can continue to play.

My question is, is it possible to make the delay 2-3 seconds before the user can press the 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() } } } 
+5
source share
3 answers

Use SKAction at the end of your createButton to execute the delay:

Scenario 1, you use SKScene to handle all touch events (this is what you should do, since restartButton is 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 use 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 wrote 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 touchhesBegan properly. You are tuned to where the user touches somewhere on the stage, the game will restart.

You need to target a specific node for this to happen.

I have added touchBegan changes to meet your needs. You will need to call your game scene what is in the case statement in order to make it 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:() } } } 
+1
source

I usually make my own timer and put it in .update () for things that don't need precise control ... there are Delta-Time actions and functions for that. I will redo this answer easier than the previous one:

Below we create a namespace for several variables, an enumeration timer and use this to update our clock, and also use it as a logical state for whether we need to act when clicking restartButton .

The frame rate is assumed to be 60, so the update is called 60 timers per second. Thus, we add a tick every time, and after 60 ticks we know that there was a second. This is inaccurate, and for games with a frame rate lower than 60 frames, you will need to do some math with delta time in order to correctly set timings (or use a different approach).

But in this simple example, I keep it simple for the main timer, so you can have explicit control over everything in your scene.

Basically, as soon as we reach 3 seconds, it will be time.toPlay = true, making the conditional statement "true", which allows us to execute the click() function that you created. Afterword, it will reset time.toPlay to false, so if you click the button again nothing will happen:

This essentially gives you 3 seconds when you are not allowed to touch the button, as it disappears and nothing. Personally IMO, 2 seconds would be better than 3, especially since your fadein is 1.5 seconds:

 // In GameScene field area: enum time { static var ticks = 0 static var seconds = 0 static var toPlay = false } // In update(): time.ticks += 1 if time.ticks >= 60 { time.seconds += 1; time.ticks = 0 } if time.seconds >= 2 { time.seconds = 0; time.toPlay = true } // In the code block where you detect restartButton: if time.toPlay { // Call your restartGame function here: // ... } else { return } 
0
source

You can use the function to wait a few seconds and then call the createButton () function


You can use this as

 self.perform(#selector(self.createButton), with: nil, afterDelay: 2.0) 

Then it will be called later.

-2
source

Source: https://habr.com/ru/post/1261506/


All Articles