내 Swift 게임은 SpriteKit 및 SKPhysics를 사용하여 게임 중에 다른 물리학 자와 자주 충돌하는 작은 빨간 공을 움직입니다. 공이 충돌 할 때마다 자연스러운 소리가 나는 바운스 효과음을 내고 싶습니다. 나는 현재이 작업을 수행하는 다소 무질서한 방법이 있고, 거기를 사용하는 동안 상당한 지연 내가 소리를 사용하지 않는 경우 사라집니다 눈에 띄는입니다 :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")
}
}
}
이는 소리 "Bounce.mp3"세 AVAudioPlayers를 생성하고합니다 (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) 메서드를 호출합니다. 따라서 공이 플랫폼과 가볍게 충돌하면 실제 충돌보다 소리가 작습니다.
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을 통해 사이클입니다 : 여기에 playBounceSound 방법입니다. 호출 될 때마다 주어진 볼륨에서 bouncePlayerIndex의 bounceSoundPlayer에게 play()를 지시합니다. 그런 다음 bouncePlayerIndex를 증가시켜 다음에 호출 할 때 다른 AVAudioPlayer를 사용합니다. bouncePlayerIndex> 2이면 0으로 되돌아갑니다. 3 개의 AVAudioPlayers를 사용하면 여러 개의 바운스를 동시에 재생할 수 있습니다. 즉, 바운스 사운드는 플랫폼에있는 공이 튀고 높이가 올라간 다음 낮아지고 뒤쪽이 튀어 오르는 것처럼 끝날 때까지 시작될 수 있습니다. 낮추고 더 자주, 튀는 것을 멈출 때까지.
AVAudioPlayers 배열보다이 방법이 더 좋습니다. 도와주세요.
당신은 이것을 보았습니까 : http://largepixels.net/post/1020? – Confused