我正在快速创建一个简单的纸牌匹配游戏。我想要在我的代码中添加 5 秒的延迟,这样当点击 2 张卡片时,在它自行返回之前会有 5 秒的延迟,而不必再次点击它。下面是我当前的代码:
import UIKit
import AVFoundation
import SwiftUI
class FirstViewController: UIViewController {
// MARK: - IBOutlets
@IBOutlet weak var c0: UIButton!
@IBOutlet weak var c1: UIButton!
@IBOutlet weak var c2: UIButton!
@IBOutlet weak var c3: UIButton!
@IBOutlet weak var c4: UIButton!
@IBOutlet weak var c5: UIButton!
@IBOutlet weak var c6: UIButton!
@IBOutlet weak var c7: UIButton!
@IBOutlet weak var c8: UIButton!
@IBOutlet weak var c9: UIButton!
@IBOutlet weak var c10: UIButton!
@IBOutlet weak var c11: UIButton!
@IBOutlet weak var timerLabel: UILabel!
@IBOutlet weak var numberOfPairsLabel: UILabel!
// MARK: - Variables and Constants
var buttonsArray = [UIButton]()
var answers = [Int]()
var faceDown = [true, true, true, true, true, true, true, true, true, true, true, true]
var matchedCards = [false, false, false, false, false, false, false, false, false, false, false, false]
var randCard = -1
var cardDrawn = -1
var numFaceUp = 0
var disabledCards = false
var numberOfPairs = 0
var player: AVAudioPlayer!
var timeRemaining = 30
var timer = Timer() //variable type is timer
@objc func countDown() {
if timeRemaining > 0 {
timeRemaining -= 1
timerLabel.text = String(timeRemaining)
} else {
GameOver()
timerLabel.text = String(timeRemaining)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let secondViewController = storyboard.instantiateViewController(withIdentifier: "gameOverPopUp") as! SecondViewController
self.present(secondViewController, animated: true, completion: nil)
}
}
// end countDown function
func GameOver() {
timer.invalidate()
performSegue(withIdentifier: "popUpView", sender: self)
}
@IBAction func cardClicked(_ sender: UIButton) {
cardDrawn = Int(sender.restorationIdentifier!)!
//if card is currently facedown, then show card number that matches drawn card
if (faceDown[cardDrawn] == true){
buttonsArray[cardDrawn].setBackgroundImage(UIImage(named: String(answers[cardDrawn])), for: .normal)
faceDown[cardDrawn] = false
}
//if card is face-up then show back of the card
else{
buttonsArray[cardDrawn].setBackgroundImage(UIImage(named: "back"), for: .normal)
faceDown[cardDrawn] = true
}
//check how many cards are currently faced up
numFaceUp = faceDown.filter({$0 == false}).count
print(numFaceUp)
if numFaceUp == 2{
disabledCards = true
// Delay the card turning back around
}
//Checking how many cards are currently faced up
numFaceUp = faceDown.filter({$0 == false}).count
// if 2 cards are face-up then disable all other cards untill they are bith face down again or a match is found.
if disabledCards == true {
var flippedCardFound = false
var cardPos1 = -1
var cardPos2 = -1
if numFaceUp == 2{
//is card at i is facedown then disable it.
for i in 0...11{
if (faceDown[i] == true)
{
buttonsArray[i].isUserInteractionEnabled = false
}
//if card is face up record its position
if (faceDown[i] == false && flippedCardFound == false){
cardPos1 = i
flippedCardFound = true
}
//if te second card is face up record its position
else if (faceDown[i] == false && flippedCardFound == true){
cardPos2 = i
}
}
}
if ((cardPos2 != -1) && (answers[cardPos1]==answers[cardPos2])){
matchedCards[cardPos1] = true
matchedCards[cardPos2] = true
buttonsArray[cardPos1].isUserInteractionEnabled = false
buttonsArray[cardPos2].isUserInteractionEnabled = false
numFaceUp = 0
if (matchedCards.filter({ $0 == true}).count) == 12{
let alertController = UIAlertController(title: "You did it!", message: "Congradulations!", preferredStyle: UIAlertController.Style.alert)
alertController.addAction(UIAlertAction(title: "Okay", style: UIAlertAction.Style.default,handler: nil))
self.present(alertController, animated: true, completion: nil)
}
}
}
//if number of face-up cards is back to 0 then reenable unmatched cards.
if numFaceUp == 0 {
disabledCards = false
faceDown = [true, true, true, true, true, true, true, true, true, true, true, true]
for i in 0...11{
if matchedCards[i] == false{
buttonsArray[i].isUserInteractionEnabled = true
}
}
}
if timeRemaining == 0 {
GameOver()
}
}
@IBAction func newGameAction(_ sender: UIButton) {
newGame()
}
func runTimer() {
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(countDown), userInfo: nil, repeats: true)
}
func newGame (){
timer.invalidate()
timerLabel.text = "30"
timeRemaining = 30
disabledCards = false
numFaceUp = 0
faceDown = [true, true, true, true, true, true, true, true, true, true, true, true]
matchedCards = [false, false, false, false, false, false, false, false, false, false, false, false]
//this loop sets the background of each button to "back and enables each button.
for i in 0...11{
buttonsArray[i].isUserInteractionEnabled = true
buttonsArray[i].setBackgroundImage(UIImage(named: "back"), for: .normal)
}
//removes all answers from answers array so that new ones can be added at the start of each game
answers.removeAll()
//this array will be used to create the array for the random card draw
//each number is in there twice to represent the same card twice
var nums = [0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5]
//this loop randomely selects a number form the nums array and then appends that number to the next
//available positions in the answers array. That number is then removed from the nums array so that it cannot be used twice
for i in 0...11{
let randCard = Int(arc4random_uniform(UInt32(nums.count)))
answers.append(nums[randCard])
//[2, 1, 4]
nums.remove(at: randCard)
//[0, 1, 3, 5, 0, 2, 3, 4, 5]
}
print(answers)
}
override func viewDidAppear(_ animated: Bool) {
buttonsArray = [c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11]
newGame()
playSound()
runTimer()
}
//if {
//numberOfPairs = numberOfPairs + 1
//numberOfPairsLabel.text = (numberOfPairs)
//}
// MARK: - IBActions and Functions
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
func playSound() {
let url = Bundle.main.url(forResource: "Audio.mp3", withExtension: nil)
player = try! AVAudioPlayer(contentsOf: url!)
player!.play()
}
// func stopSound() {
// player?.stop()
// stopButton.setImage(UIImage(systemName: "speaker.fill"), for: .normal)
// }
// }
// @IBAction func stopButton(_ sender: UIButton) {
// }
// @IBOutlet weak var stopButton: UIButton!
//stopButton.setImage(UIImage(systemName: "speaker.slash.fill"), for: .normal)
}
您可以使用GCD并编写以下内容:
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
// Turn cards back
}