我的Swift遊戲使用SpriteKit和SKPhysics來動畫在遊戲過程中經常與其他physicsBodys碰撞的小紅球。每當球發生碰撞時,我都想創建一個自然的彈跳音效。我現在有這樣做的一個比較無序的方法,並有一個顯著的滯後明顯,而使用它,當我禁用聲音會消失:在SpriteKit中創建彈跳球的聲音效果
var bounceSoundPlayers = [AVAudioPlayer!]()
func buildBounceSound() {
let path = Bundle.main.path(forResource: "Bounce.mp3", ofType:nil)!
let url = URL(fileURLWithPath: path)
for _ in 0...2 {
do {
let sound = try AVAudioPlayer(contentsOf: url)
sound.prepareToPlay()
bounceSoundPlayers.append(sound)
} catch {
fatalError("couldn't load music file")
}
}
}
這將創建三個AVAudioPlayers有聲「Bounce.mp3」並運行prepareToPlay( )方法。然後將它們存儲在名爲bounceSoundPlayers的數組中,以便稍後使用它們。然後,我有一個didBeginContact方法被稱爲一旦有事情與任何碰撞:
func didBegin(_ contact: SKPhysicsContact) {
if contact.collisionImpulse > 0.45 && defaults.bool(forKey: "SFX") {
if ((contact.bodyA.node!.name == "ball" && contact.bodyB.node!.name == "permeable platform") ||
(contact.bodyB.node!.name == "ball" && contact.bodyA.node!.name == "permeable platform") ||
(contact.bodyA.node!.name == "ball" && contact.bodyB.node!.name == "ring") ||
(contact.bodyB.node!.name == "ball" && contact.bodyA.node!.name == "ring"))
&&
ball.collidingWithPermeable {
playBounceSound(contact.collisionImpulse/8<=1 ? contact.collisionImpulse/8 : 1)
}
if (contact.bodyA.node!.name == "ball" && contact.bodyB.node!.name == "impermeable platform") ||
(contact.bodyB.node!.name == "ball" && contact.bodyA.node!.name == "impermeable platform") ||
(contact.bodyA.node!.name == "ball" && contact.bodyB.node!.name == "wall") ||
(contact.bodyB.node!.name == "ball" && contact.bodyA.node!.name == "wall") {
playBounceSound(contact.collisionImpulse/5<=1 ? contact.collisionImpulse/5 : 1)
}
}
}
基本上,這種方法確實是它會檢查每一次碰撞,如果球在正確的平臺或牆壁的碰撞,它會調用方法playBounceSound(體積:CGFloat),體積與碰撞力成正比。因此,如果球輕輕碰撞平臺,音量就會比真正強烈的碰撞更安靜。這裏的playBounceSound方法:
var bouncePlayerIndex = Int(0)
func playBounceSound(_ volume: CGFloat) {
let previousIndex = bouncePlayerIndex - 1 >= 0 ? bouncePlayerIndex - 1 : 2
if bounceSoundPlayer[previousIndex].isPlaying {
if bounceSoundPlayer[previousIndex].currentTime > 0.1 {
bounceSoundPlayer[bouncePlayerIndex].volume = Float(volume)
bounceSoundPlayer[bouncePlayerIndex].play()
}
}
else {
bounceSoundPlayer[bouncePlayerIndex].volume = Float(volume)
bounceSoundPlayer[bouncePlayerIndex].play()
}
bouncePlayerIndex += 1
if bouncePlayerIndex > 2 {bouncePlayerIndex = 0}
}
基本上,這個方法所做的就是通過我們前面使用索引整數創建的三個AVAudioPlayers週期。每次調用它時,它都會告知bouncePlayerIndex的bounceSoundPlayer在給定音量處播放()。然後它會增加bouncePlayerIndex,以便下次調用它時,它會使用不同的AVAudioPlayer。如果bouncePlayerIndex> 2,它會回到0.使用三個AVAudioPlayers可以同時彈奏多次彈跳 - 也就是說,彈跳音可以在最後一次彈跳結束之前開始,例如當球落在平臺上並彈跳高時,然後降低更低和更頻繁,直到它停止彈跳。
我相信有一個比AVAudioPlayers數組更好的方法。請幫忙。
你見過這個:http://largepixels.net/post/1020? – Confused