jacobbullon
jacobbullon

Reputation: 17

Set a delay after UIButton activation

I am working on a dice game that rolls 4 dice with random numbers assigned to each of them. When I press the roll button, the sound effect plays as intended and the images are replaced, but I am looking for a way to prevent the user from pressing roll until the sound effect is finished (maybe 2 seconds).

This is my function that updates dice images, where I have been testing this problem by adding DispatchTime.now() + 2 to the if statements and before arc4random_uniform, but to no avail:

func updateDiceImages() {
    randomDiceIndex1 = Int(arc4random_uniform(6))
    randomDiceIndex2 = Int(arc4random_uniform(6))
    randomDiceIndex3 = Int(arc4random_uniform(6))
    randomDiceIndex4 = Int(arc4random_uniform(6))
    randomMultiplier = Int(arc4random_uniform(4))

    // determine the operator dice at random
    if randomMultiplier == 0 {
        addDice()
    }
    if randomMultiplier == 1 {
        subDice()
    }
    if randomMultiplier == 2 {
        divDice()
    }
    if randomMultiplier == 3 {
        multDice()
    }

    // image changes to random dice index
    diceImageView1.image = UIImage(named: diceArray[randomDiceIndex1])

    diceImageView2.image = UIImage(named: diceArray[randomDiceIndex2])

    diceImageView3.image = UIImage(named: diceArray[randomDiceIndex3])

    diceImageView4.image = UIImage(named: diceArray[randomDiceIndex4])

    multImageView1.image = UIImage(named: multArray[randomMultiplier])
}     

If necessary, here is also my function that plays the sound effect, where I also tried implementing DispatchTime.now() + 2:

func rollSound() {
    // Set the sound file name & extension
    let alertSound = URL(fileURLWithPath: Bundle.main.path(forResource: "diceRoll", ofType: "mp3")!)

    do {
        // Preparation
        try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
    } catch _ {
    }
    do {
        try AVAudioSession.sharedInstance().setActive(true)
    } catch _ {
    }

    // Play the sound
    do {
        audioPlayer = try AVAudioPlayer(contentsOf: alertSound)
    } catch _{
    }

    audioPlayer.prepareToPlay()
    audioPlayer.play()
}      

Here is the implementation that I feel is the closest, but I get many errors:

    func rollSound() {
    // Set the sound file name & extension
    let when = DispatchTime.now() + 2 // change 2 to desired number of seconds
    DispatchQueue.main.asyncAfter(deadline: when) {
        let alertSound = URL(fileURLWithPath: Bundle.main.path(forResource: "diceRoll", ofType: "mp3")!)

        do {
            // Preparation
            try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
        } catch _ {
        }
        do {
            try AVAudioSession.sharedInstance().setActive(true)
        } catch _ {
        }

        // Play the sound
        do {
            audioPlayer = try AVAudioPlayer(contentsOf: alertSound)
        } catch _{
        }

        audioPlayer.prepareToPlay()
        audioPlayer.play()
    }
}

Upvotes: 1

Views: 364

Answers (1)

Dharmesh Kheni
Dharmesh Kheni

Reputation: 71852

I have updated code for your error.

func rollSound() {
    // Set the sound file name & extension
    let when = DispatchTime.now() + 2 // change 2 to desired number of seconds
    DispatchQueue.main.asyncAfter(deadline: when) {
        let alertSound = URL(fileURLWithPath: Bundle.main.path(forResource: "diceRoll", ofType: "mp3")!)

        do {
            // Preparation
            try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
        } catch _ {
        }
        do {
            try AVAudioSession.sharedInstance().setActive(true)
        } catch _ {
        }

        // Play the sound
        do {
            self.audioPlayer = try AVAudioPlayer(contentsOf: alertSound)
        } catch _{
        }

        self.audioPlayer?.prepareToPlay()
        self.audioPlayer?.play()
    }
}

You need to add self to the property if you want to use class instance into DispatchQueue closer. and same for updateDiceImages()

Upvotes: 1

Related Questions