在 SwiftUI 中是否可以一次只允许一个 onTapGesture 输入?

时间:2021-04-19 19:55:41

标签: ios swift iphone xcode swiftui

我是 Swift 的新手,所以请原谅我对这个主题的无知。我正在尝试编写一个简单的 Tic Tac Toe 游戏作为学习 Swift 的个人项目,但我一直遇到一个问题,如果用户要同时点击多个空格,游戏会将“X”放在两个地方。

我已经设置为一旦用户点击一个空格,一个名为“playerTurn”的变量就会切换为 false 以防止用户点击另一个位置,直到 AI 完成它的回合,此时,它会切换玩家转回真。切换发生在“updateBlock()”函数中。每次用户点击一个空格时,if 语句都会检查是否轮到玩家了。

问题是,如果用户在合适的时间点击两个或多个空格,两个空格中的函数都会执行,因为它没有足够的时间将 playerTurn 切换为 false。我有下面的一段代码。我确定我遗漏了一些明显的东西,但我似乎无法弄清楚如何让它按照我需要的方式工作。非常感谢任何帮助!

HStack {
    Spacer()
    Image(iconArray[blockValue[0]])
        .resizable()
        .aspectRatio(1, contentMode: .fit)
        .background(Color.accentColor)
        .cornerRadius(20)
        .scaleEffect(0.9)
        .onTapGesture {
            if playerTurn == true && zeroBlocksExist[0] == true {
                // Ensure that it is the player's turn and that the space is vacant before updating the space with the new value
                updateBlock(blockPosition: 0)
            }
        }
    Image(iconArray[blockValue[1]])
        .resizable()
        .aspectRatio(1, contentMode: .fit)
        .background(Color.accentColor)
        .cornerRadius(20)
        .scaleEffect(0.9)
        .onTapGesture {
            if playerTurn == true && zeroBlocksExist[1] == true {
                // Ensure that it is the player's turn and that the space is vacant before updating the space with the new value
                updateBlock(blockPosition: 1)
            }
        }
    Image(iconArray[blockValue[2]])
        .resizable()
        .aspectRatio(1, contentMode: .fit)
        .background(Color.accentColor)
        .cornerRadius(20)
        .scaleEffect(0.9)
        .onTapGesture {
            if playerTurn == true && zeroBlocksExist[2] == true {
                // Ensure that it is the player's turn and that the space is vacant before updating the space with the new value
                updateBlock(blockPosition: 2)
            }
        }
    Spacer()
}

// updateBlock function 

func updateBlock(blockPosition: Int) {
        DispatchQueue.global().async {
            if movesCount < 9 {
                if playerTurn == true {
                    playerTurn.toggle() // Disable player turn
                    titleText = "CPU's turn"
                    restartButtonState.toggle() // Disable the restart button until after the CPU does its turn
                    blockValue[blockPosition] = 1 // Put the X icon in the requested space
                    if allowSounds {
                        playAudio(soundName: "pop-1", soundExt: "mp3") // Play the pop sound effect
                    }
                    checkVacantBlocks() // Check vacant blocks and update the array
                } else if playerTurn == false {
                    blockValue[blockPosition] = 2 // Put the O icon
                    playerTurn.toggle()
                    titleText = "Your turn"
                    restartButtonState.toggle() // Enable the restart button
                    checkVacantBlocks()
                }
                movesCount += 1
                print("Moves made: ", String(movesCount))
            } else if movesCount >= 9 {
                print("Game board full!")
                checkWinnings()
            }
            return
        }
        
    }

0 个答案:

没有答案