AVAudioPlayer在动画时导致SpriteNodes抖动

时间:2016-05-23 09:51:49

标签: swift skspritenode

我正在使用app atm,用户可以在屏幕上看到动画节点。当节点通过某个目标区域时,用户必须按下一个按钮,然后播放一个avplayer声音。

问题是,无论何时用户按下按钮并播放声音,节点都会抽搐,我不明白为什么。要复制我遇到的问题,这是一个我在几分钟内放在一起的示例项目。

import SpriteKit
class GameViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let skView = self.view as! SKView

        let scene = GameScene(size: CGSizeMake(self.view.frame.size.width, self.view.frame.size.height))

        skView.presentScene(scene)
    }
}

import SpriteKit
import AVFoundation
class GameScene: SKScene {

    var buttonNode : SKSpriteNode?

    override init(size: CGSize)
    {
        super.init(size: size)

        self.backgroundColor = SKColor.whiteColor()
        self.view?.backgroundColor = UIColor.whiteColor()
    }

    override func didMoveToView(view: SKView)
    {
        buttonNode = SKSpriteNode(imageNamed: "button")
        buttonNode?.name = "button"
        buttonNode?.position = CGPointMake(200, 200)
        buttonNode?.size = CGSizeMake(150, 150)
        self.addChild(buttonNode!)

       NSTimer.scheduledTimerWithTimeInterval(1.5, target: self, selector: #selector(self.animateNodes), userInfo: nil, repeats: true)
    }

    var avPlayer : AVAudioPlayer?
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)
    {
        for touch in touches
        {
            let viewTouchLocation = touch.locationInView(self.view)
            let sceneTouchPoint = self.convertPointFromView(viewTouchLocation)
            let touchedNode = self.nodeAtPoint(sceneTouchPoint)
            if(touchedNode.name == "button")
            {
                let avURL = NSURL.fileURLWithPath(NSBundle.mainBundle().pathForResource("exampleSound", ofType: "wav")!)
                avPlayer = try? AVAudioPlayer(contentsOfURL: avURL)
                avPlayer?.volume = 0.2
                avPlayer?.play()
            }
        }
    }

    func animateNodes()
    {
        let sprite = SKSpriteNode(imageNamed: "shortMetalWhite")
        sprite.color = UIColor.blackColor()
        sprite.colorBlendFactor = 1.0
        sprite.position = CGPointMake(self.view!.frame.size.width, 400)

        self.addChild(sprite)
        let noteDuration = 4.0
        let actionMove = SKAction.moveTo(CGPointMake(-5, 400), duration: noteDuration)
        let actionMoveDone = SKAction.removeFromParent()
        sprite.runAction(SKAction.sequence([actionMove, actionMoveDone]))
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

有谁知道是什么原因引起的? sprite节点和avplayer是否有问题导致这种情况?我在非游戏应用程序中复制了相同的代码,在屏幕上有一系列UIViews动画,每次按下按钮都会播放声音,并且没有任何滞后或急动的问题。那么sprite节点和AVPlayer导致这个问题的是什么呢?

(顺便说一句,这个问题在模拟器上并不明显,但是当你在任何iPhone或iPad上运行时,它都非常明显)

非常感谢任何帮助

编辑:

如果我改为使用AudioServices而不是像这样

if let soundURL = NSBundle.mainBundle().URLForResource("OHH10 Drums1DOTcom", withExtension: "wav") {
                    var mySound: SystemSoundID = 0
                    AudioServicesCreateSystemSoundID(soundURL, &mySound)
                    // Play
                    AudioServicesPlaySystemSound(mySound);
                }

没有滞后,但是我无法控制音量。所以不是一个理想的解决方案

1 个答案:

答案 0 :(得分:0)

经过更多的研究,它似乎是AVAudioPlayer的一个问题,它不适合短时间连续播放重复声音效果。

所以改为使用

SKAction.playSoundFileNamed("example.wav", waitForCompletion: false)

再次问题是它不允许你控制音量。这意味着我必须打开audacity并修改每个声音文件的音量以使其恰到好处。

我本来希望有一个更好的解决方案,但遗憾的是,如果我想避免任何游戏延迟,这是我能找到的最好的