SKAudioNode播放声音一次

5

我似乎找不到关于SKAudioNode的太多信息。如何只播放一次声音?我不想重复播放声音。

我的目标是在SpriteKit中每次生成子弹时播放短激光声音。

2个回答

14

很遗憾,@KnightOfDragon所说的不正确(但我没有足够的声望评论)。

SKAudioNode在iOS 9中被引入,旨在替代SKAction.playSoundFileNamed(...)因为它更加强大(您可以将其作为SpriteKit SKNode的子节点添加,如果将属性positional设置为true,则自动添加3D音频混合)。

若要使用SKAudioNode播放一次声音,请使用以下代码:

if #available(iOS 9, *) {
    let pling = SKAudioNode(fileNamed: "pling.wav")
    // this is important (or else the scene starts to play the sound in 
    // an infinite loop right after adding the node to the scene).
    pling.autoplayLooped = false
    someNode.addChild(pling)
    someNode.runAction(SKAction.sequence([
        SKAction.waitForDuration(0.5),
        SKAction.runBlock {
            // this will start playing the pling once.
            pling.runAction(SKAction.play())
        }
    ])
}
else {
    // do it the old way
}

更新

看一下这里,如何在音频节点上使用Actions: SKAction->Audio-Stuff。文档中说:

仅对短暂的插曲使用SKAction playSoundFileNamed:waitForCompletion:。对于长时间运行的背景音乐,请使用AVAudioPlayer。

这并不意味着不能使用SKAudioNode进行一次性音频。使用playSoundFileNamed无法更改音量或暂停/停止播放等。


2
@Knight0fDragon:我不同意,因为playSoundFileNamed没有位置音频或任何更复杂的选项,它是为了轻松地进行一次性音频而设计的,没有任何控制。另一方面,AVFoundation更加复杂,不太容易集成到SpriteKit中。SKAudioNode是一种将AVFoundation集成到SpriteKit中的简单方法(因为它在幕后使用AVFoundation)。但更重要的是,我认为SKAudioNode主要不是用于音乐,因为您可以将其用于定位音频,这不太可能用于音乐。 - Juangamnik
1
@Juangamnik 不确定您是否遇到过这个问题,但是SKAudioNode在说话时(耳机故障)目前存在问题。 在此处阅读更多信息https://dev59.com/nVsV5IYBdhLWcg3w4iP- - Whirlwind
1
@Whirlwind 非常感谢,所以你的解决方案是直接使用 AVAudioPlayer。对吧?对于我的背景音乐,我无论如何都会使用 AVAudioPlayer,因为据我所知,SKAudioNode 的缺点是在整个游戏过程中(包括场景转换)不能使用它。我只用 SKAudioNode 来做特效。这就是为什么我想要只播放一次声音的原因。 - Juangamnik
1
@Juangamnik 个人而言,当我需要控制声音时,例如背景音乐或可能需要在随机时刻暂停的循环(如果 SKAudioNode 没有出现问题,我会使用它来代替这些循环),我会使用 AVAudioPlayer。否则,对于短声音,我使用 SKAction.playSoundFileNamed,但不幸的是,它也存在一些错误 - Whirlwind
1
此外,如果我需要对短声音进行任何类型的控制,而SKAudioNode提供了这种控制,我可能会使用SKAudioNode,只要我能保持良好的性能... - Whirlwind
显示剩余8条评论

6
如果您想实现音效效果,可以在创建效果的精灵上使用 SKAction.playSoundFileNamed(...)。而 SKAudioNode 更适合在游戏中播放音乐。
例如:
//we have ship as an SKSpriteNode

//lets fire laser

ship.runAction(SKAction.playSoundFileNamed("pewpewpew.caf",waitForCompletion:false));

谢谢!太棒了,非常简单。我该如何预加载声音?现在游戏第一次播放声音时会冻结0.1秒。 - Glutch
1
我相信你可以在加载时将动作保存在自己的变量中 let pewpew = SKAction.play....,然后只需调用 ship.runAction(pewpew); - Knight0fDragon
[11/9/16] 开发环境:iOS 9+和xCode 8。使用此调用存在已知的内存泄漏问题。在苹果论坛上,您会看到一个关于2016年4月内存泄漏的帖子,但至今仍未修复。 - cbuck12000
但是这样你就无法控制播放的音量。 - Kirby Todd
@KirbyTodd 我已经好几年没碰这个东西了,但我相信在播放之前你可以控制音量。 - Knight0fDragon
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接