ios - 等待 Swift 计时器完成

标签 ios swift timer wait swift5

所以我在 swift 5 上做一个简单的游戏,我基本上有一个 3..2..1.. go 计时器来开始游戏,然后有一个 3..2..1..stop 计时器来停止游戏。最后是显示分数的函数。我需要一种方法让每个函数调用在下一个函数调用开始之前等待计时器完成,有什么建议吗?到目前为止,这是我的代码。 (此外,如果您对该应用程序有任何其他建议,也请告诉我,最终目标是记录您在 3 秒内可以点击按钮的次数)

var seconds = 3 //Starting seconds
var countDownTimer = Timer()
var gameTimer = Timer()
var numberOfTaps = 0

override func viewDidLoad() {
    super.viewDidLoad()

    self.startCountdown(seconds: seconds)
    self.gameCountdown(seconds: seconds)
    self.displayFinalScore()


}

func startCountdown(seconds: Int) {
        countDownTimer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { [weak self] timer in
            self?.seconds -= 1
            if self?.seconds == 0 {
                self?.countdownLabel.text = "Go!"
                timer.invalidate()
            } else if let seconds = self?.seconds {
                self?.countdownLabel.text = "\(seconds)"
            }
        }
}

func gameCountdown(seconds: Int) {
        gameTimer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { [weak self] timer in
              self?.seconds -= 1
              if self?.seconds == 0 {
                  self?.countdownLabel.text = "Stop!"
                  timer.invalidate()
              } else if let seconds = self?.seconds {
                  self?.countdownLabel.text = "\(seconds)"
              }
          }
  }


    deinit {
        // ViewController going away.  Kill the timer.
        countDownTimer.invalidate()
    }




@IBOutlet weak var countdownLabel: UILabel!


@IBAction func tapMeButtonPressed(_ sender: UIButton) {
    if gameTimer.isValid {
        numberOfTaps += 1
    }
}

func displayFinalScore() {
    if !gameTimer.isValid && !countDownTimer.isValid {
        countdownLabel.text = "\(numberOfTaps)"
    }
}

最佳答案

您应该考虑您的游戏可能处于的状态。它可能是 -

  • 设置 - 建立游戏
  • 开始 - 前三秒
  • 运行 - 在前三秒之后但在结束之前
  • 结束 - 最后三秒
  • 结束 - 时间到了。

每次计时器计时,您都需要考虑需要采取什么操作以及需要进入什么状态。您没有说您希望游戏持续多长时间,但假设是 30 秒。

开始新游戏时,您处于setup状态;该按钮被禁用(即它不会对点击使用react),并且您将分数设置为 0。您将进入 starting 状态。 在开始中显示倒计时。三秒钟后,您启用按钮并进入运行状态。 一旦到达 27 秒,您就会进入结束状态并显示结束倒计时 最后时间到了,您进入结束状态,禁用按钮并显示分数。

你可以像这样编写代码


enum GameState {

    case setup
    case starting
    case running
    case ending
    case ended
}

class ViewController: UIViewController {

    @IBOutlet weak var startButton: UIButton!
    @IBOutlet weak var tapButton: UIButton!
    @IBOutlet weak var countdownLabel: UILabel!

    var gameState = GameState.ended
    var gameTimer:Timer?
    var numberOfTaps = 0
    var gameStartTime = Date.distantPast
    let GAMEDURATION: TimeInterval = 30

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    @IBAction func startButtonTapped(_ sender: UIButton) {
        self.startGame()
    }

    @IBAction func tapMeButtonPressed(_ sender: UIButton) {
        self.numberOfTaps += 1
    }

    func startGame() {
        self.gameState = .setup

        self.gameTimer = Timer.scheduledTimer(withTimeInterval:0.1, repeats: true) { timer in

            let elapsedTime = -self.gameStartTime.timeIntervalSinceNow
            let timeRemaining = self.GAMEDURATION-elapsedTime
            switch self.gameState {
            case .setup:
                self.gameStartTime = Date()
                self.tapButton.isEnabled = false
                self.startButton.isEnabled = false
                self.numberOfTaps = 0
                self.gameState = .starting
            case .starting:
                if elapsedTime > 2.5 {
                    self.gameState = .running
                    self.tapButton.isEnabled = true
                    self.countdownLabel.text  = "Go!"
                } else {
                    let countdown = Int(3-round(elapsedTime))
                    self.countdownLabel.text = "\(countdown)"
                }
            case .running:
                if timeRemaining < 4 {
                    self.gameState = .ending
                }
            case .ending:
                let countdown = Int(timeRemaining)
                self.countdownLabel.text = "\(countdown)"
                if timeRemaining < 1 {
                    self.countdownLabel.text = "Stop"
                    self.gameState = .ended
                    self.tapButton.isEnabled = false
                }
            case .ended:
                if timeRemaining <= 0 {
                    self.countdownLabel.text = "You tapped the button \(self.numberOfTaps) times"
                    self.startButton.isEnabled = true
                    self.gameTimer?.invalidate()
                    self.gameTimer = nil
                }
            }
        }
    }
}

关于ios - 等待 Swift 计时器完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61945319/

相关文章:

ios - NSMutableArray 线程并发与 GCD

iphone - iOS UIActivity View Controller Opera 迷你按钮?

ios - Swift vs ObjC 初始化过程?

C# 计时器在整秒开始

C# 计时器 Azure SQL 函数

ios - 是否可以使 main bundle 在 IOS 中可写?

ios - ActionSheetPickerClass , iOS

ios - UIView 可以为自己分配一个 UITapGestureRecognizer 吗?

swift - 为什么我可以在 Swift 中将 NSNumber 的值设置为 true/false?

java - 定时器.schedule api : Why the timer task executes even the first time has passed