【问题标题】:Adding sound effects in Spritekit在 Spritekit 中添加音效
【发布时间】:2016-07-16 09:24:18
【问题描述】:

我正在制作一款 Flappy Bird 类型的游戏,我想在收集硬币时添加音效。这就是我所拥有的:

import SpriteKit
import AVFoundation

class GameScene: SKScene {

    var coinSound = NSURL(fileURLWithPath:NSBundle.mainBundle().pathForResource("Super Mario Bros.- Coin Sound Effect", ofType: "mp3")!)
    var audioPlayer = AVAudioPlayer()

稍后在我的 didMoveToView 中:

audioPlayer = AVAudioPlayer(contentsOfURL: coinSound, error: nil)
audioPlayer.prepareToPlay()

对于第二部分(在我的 didMoveToView 中),第一行一直显示错误:

调用可以抛出,但是没有标记'try'并且错误没有处理

我该如何解决这个问题?

【问题讨论】:

  • 这个在被答案纠正后,真的会播放声音吗?
  • 我知道你已经标记了一个答案,但我实际上会使用 SKAction.playSound... 短 1 次声音。 AVFoundation 更适合用于背景音乐。

标签: ios swift audio sprite-kit


【解决方案1】:

我知道您已经标记了一个答案,但如果您重新阅读此问题或为未来的读者使用 SKActions 播放短 1 次声音更容易。

AVFoundation 更适合用于背景音乐。

例如

class GameScene: SKScene {

     // add as class property so sound is preloaded and always ready
     let coinSound = SKAction.playSoundFileNamed("NAMEOFSOUNDFILE", waitForCompletion: false)
}

当你需要播放声音时,只需说这个

run(coinSound)

希望对你有帮助

【讨论】:

  • 我现在正在使用这种方式。这是一个 SHIT TONNE 更容易,如果动作是预先创建的,似乎正在缓存音频文件,所以第一次播放时没有加载/延迟。
  • 是的。我实际上并没有意识到这是一个 7 个月大的问题,以为是新问题。
【解决方案2】:
audioPlayer = AVAudioPlayer(contentsOfURL: coinSound, error: nil)

这不再是 Swift 处理错误的方式。您必须使用 do-try-catch 语法。

do {
    audioPlayer = try AVAudioPlayer(contentsOfURL: coinSound)
    audioPlayer.prepareToPlay()
}
catch let error {
    // handle error
}

或者,如果您不想编写任何错误处理代码,您可以将 audioPlayer 变量设为可选并编写可失败的 try?

audioPlayer = try? AVAudioPlayer(contentsOfURL: coinSound)
audioPlayer?.prepareToPlay()

这更接近于您尝试将 nil 传递给错误参数的代码。

或者如果发生错误时崩溃是适当的行为,您可以采用这种方法:

guard let audioPlayer = try? AVAudioPlayer(contentsOfURL: coinSound) else {
    fatalError("Failed to initialize the audio player with asset: \(coinSound)")
}
audioPlayer.prepareToPlay()
self.audioPlayer = audioPlayer

【讨论】:

  • 如果您有时间,并且愿意,您能在下面的 swift 3 版本中回答我评论中的问题吗?
  • 立即崩溃的替代方法是let audioPlayer = try! etc...。您不会收到详细的错误消息,但如果您正在调试,那么 Xcode 无论如何都会查明位置。
【解决方案3】:

斯威夫特 3.0+

对于上述来自@nhgrif 的guard let 示例,这种 Swift 3.0+ 的实现方式:

var coinSound = NSURL(fileURLWithPath:Bundle.main.path(forResource: "Super Mario Bros.- Coin Sound Effect", ofType: "mp3")!)
var audioPlayer = AVAudioPlayer()

func playCoinSound(){
    guard let soundToPlay = try? AVAudioPlayer(contentsOf: coinSound as URL) else {
        fatalError("Failed to initialize the audio player with asset: \(coinSound)")
    }
    soundToPlay.prepareToPlay()

//  soundToPlay.play() // NO IDEA WHY THIS DOES NOT WORK!!!???

    self.audioPlayer = soundToPlay
    self.audioPlayer.play() // But this does work... please let me know why???
}

playCoinSound()

【讨论】:

  • 我不知道。我只是从我的(越来越大的)参考文件中的所有其他警卫那里复制了它。这是从上面,nhgrif的答案。直到今天我才使用它,此时我发现了 swift 3 的变化,并对是否需要重复自己才能玩它感到好奇。
  • 问一下很酷。在这种情况下使用 return 并优雅退出可能会更好,这样您的应用就不会崩溃。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-26
  • 2015-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多