0

SpriteKit を使用せずに iOS でゲームを作成しようとしています。効果音をタイムリーに再生するのに苦労しています。私はオンラインで見つけた次のコードを使用しており、バックグラウンドミュージックは素晴らしいものです。ただし、「playSoundEffect」メソッドを使用すると、最初は正常に再生されますが、遅れて同期しなくなります。毎回 AVAudioPlayer を初期化するためだと思います。バックグラウンド ミュージックを再生しながら効果音をタイムリーに再生する方法を知っている人はいますか? ありがとう!

import AVFoundation

public class SKTAudio: NSObject, AVAudioPlayerDelegate {
public var backgroundMusicPlayer: AVAudioPlayer?
public var soundEffectPlayer: AVAudioPlayer?

private var mainLoopFileName:String! {

    let randomSong = Int(arc4random_uniform(3))

    switch randomSong {
    //case 0: return "Test.mp3"
    //case 1: return "Test2.mp3"
    case 0: return "SneakySnitch.mp3"
    case 1: return "FasterDoesIt.mp3"
    case 2: return "MonkeysSpinningMonkeys.mp3"
    default:
        break
    }

    return "SneakySnitch.mp3"
}

public class func sharedInstance() -> SKTAudio {
    return SKTAudioInstance
}

public func playBackgroundMusic() {
    let filename = mainLoopFileName
    let url = NSBundle.mainBundle().URLForResource(filename, withExtension: nil)
    if (url == nil) {
        println("Could not find file: \(filename)")
        return
    }

    var error: NSError? = nil
    backgroundMusicPlayer = AVAudioPlayer(contentsOfURL: url, error: &error)
    if let player = backgroundMusicPlayer {
        player.numberOfLoops = 0
        player.delegate = self
        player.prepareToPlay()
        player.play()
    } else {
        println("Could not create audio player: \(error!)")
    }
}

public func pauseBackgroundMusic() {
    if let player = backgroundMusicPlayer {
        if player.playing {
            player.pause()
        }
    }
}

public func resumeBackgroundMusic() {
    if let player = backgroundMusicPlayer {
        if !player.playing {
            player.play()
        }
    }
}

public func playSoundEffect(filename: String) {
    let url = NSBundle.mainBundle().URLForResource(filename, withExtension: nil)
    if (url == nil) {
        println("Could not find file: \(filename)")
        return
    }

    var error: NSError? = nil
    soundEffectPlayer = AVAudioPlayer(contentsOfURL: url, error: &error)
    if let player = soundEffectPlayer {
        player.numberOfLoops = 0
        player.prepareToPlay()
        player.play()
    } else {
        println("Could not create audio player: \(error!)")
    }
}

// MARK: AVAudioPlayerDelegate
public func audioPlayerDidFinishPlaying(player: AVAudioPlayer!, successfully flag: Bool) {
    println("finished playing \(flag)")

    delay(5.0, {
        self.playBackgroundMusic()
    })
}

public func audioPlayerDecodeErrorDidOccur(player: AVAudioPlayer!, error: NSError!) {
    println("\(error.localizedDescription)")
}

}
4

2 に答える 2

0

問題は、最初の効果音が終わる前に 2 番目の効果音を再生していることです。newAVAudioPlayersoundEffectPlayer変数に設定すると、最初の参照が強制終了され、最初の参照が停止します。

サウンドの音量を制御できなくても構わない場合は、次のように使用できます。

var mySound: SystemSoundID = 0
AudioServicesCreateSystemSoundID(url, &mySound)
// Play
AudioServicesPlaySystemSound(mySound)

それ以外の場合はAVAudioPlayer、参照を維持しながら、作成した各サウンドを配列に追加する場合に使用できます。AVAudioPlayerデリゲートを実装することで、音が鳴ったら削除することができます。

func playSound(){
    let path : NSString? = NSBundle.mainBundle().pathForResource("sound", ofType: "wav")!
    let url = NSURL(fileURLWithPath: path!)

    var error : NSError?
    let sound = AVAudioPlayer(contentsOfURL: url, error: &error)
    sound.delegate = self
    sound.volume = 0.5

    self.soundsEffectsArray.addObject(sound)
    sound.prepareToPlay()
    sound.play()
}

func audioPlayerDidFinishPlaying(player: AVAudioPlayer!, successfully flag: Bool) {
    self.soundsEffectsArray.removeObject(player)
}
于 2015-03-12T06:42:51.203 に答える