无法理解我的精灵游戏的滞后?



制作一个简单的spritekit游戏。在那里,我有声音库做的按钮触摸声音等AVFoundation。但是对此有麻烦。点击任何按钮时,我的帧速率总是下降,这听起来。但是如果我将所有声音静音,则没有延迟。这是我的代码:

import AVFoundation
class GameAudio {
    static let shared = GameAudio()
    private var buttonClickSound = AVAudioPlayer()
    private var completionSound = AVAudioPlayer()
    private var swishSound = AVAudioPlayer()
    private var gridSwishSound = AVAudioPlayer()
    private let Volume: Float = 0.8
    func setupSounds() {
        print("GameAudio setupSounds()")
        if let path = Bundle.main.path(forResource: SoundNames.ButtonClickSoundName, ofType: "mp3") {
            let url = URL(fileURLWithPath: path )
            do {
                buttonClickSound = try AVAudioPlayer(contentsOf: url)
            } catch {
                print(error)
            }
        }
        if let path = Bundle.main.path(forResource: SoundNames.CompletionSoundName, ofType: "mp3") {
            let url = URL(fileURLWithPath: path)
            do {
                completionSound = try AVAudioPlayer(contentsOf: url)
            } catch {
                print(error)
            }
        }
        if let path = Bundle.main.path(forResource: SoundNames.SwishSoundName, ofType: "mp3") {
            let url = URL(fileURLWithPath: path )
            do {
                swishSound = try AVAudioPlayer(contentsOf: url)
            } catch {
                print(error)
            }
        }
        if let path = Bundle.main.path(forResource: SoundNames.GridSwishSoundName, ofType: "mp3") {
            let url = URL(fileURLWithPath: path)
            do {
                gridSwishSound = try AVAudioPlayer(contentsOf: url)
            } catch {
                print(error)
            }
        }
        buttonClickSound.volume = Volume
        completionSound.volume = Volume
        swishSound.volume = Volume
        gridSwishSound.volume = Volume
    }
    func playButtonClickSound() {
        buttonClickSound.play()
    }
    func playCompletionSound() {
        completionSound.play()
    }
    func playSwishSound() {
        swishSound.play()
    }
    func playGridSwishSound() {
        gridSwishSound.play()
    }
}

在我的游戏视图控制器中,我调用GameAudio.shared.setupSounds()来预加载我所有的声音。

public struct Actions {
    static func buttonIsTouched(_ button: SKNode, sound: Bool, completion: @escaping () -> ()) {
        if button.hasActions() { return }
        if sound {
            GameAudio.shared.playButtonClickSound()
        }
        button.run(touchedButtonAction(scaleFactor: button.returnScaleFactor()), completion: completion)
    }
}
class MenuNode: SKNode {
    private let settings: Settings
    var delegate: MenuNodeDelegate?
    private let playButton = SKSpriteNode(imageNamed: SpriteNames.PlayButtonName)
    private let MenuNodeTreshold: CGFloat = 12.0
    init(settings: Settings) {
        self.settings = settings
        super.init()
        setupButtons()
        isUserInteractionEnabled = false
    }
    private func setupButtons() {
        playButton.position = CGPoint(x: 0.0 - playButton.frame.size.width / 2.0 - MenuNodeTreshold / 2.0, y: 0.0)
        addChild(playButton)
    }
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch in touches {
            let location = touch.location(in: self)
            if playButton.contains(location) {
                Actions.buttonIsTouched(playButton as SKNode, sound: settings.sound, completion: {
                    self.delegate?.playButtonTouched()
                })
            }
        }
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

我在游戏中的所有操作都使用Actions结构。我有buttonTouchedAction(),我在不同的节点中使用它。我用一个"播放"按钮从菜单中输入了一些代码。因此,例如,我在设备上运行我的游戏,它显示菜单节点,等待几秒钟并点击按钮,在我的帧速率下降后,我在一秒钟内出现延迟,然后场景更改为游戏场景。

如果你想

使用AVAudioPlayer(而不是SpriteKit's声音动作(,你应该让声音在后台线程中播放,这样它的操作就不会干扰你所有视觉内容所在的主线程:

 let soundQueue = OperationQueue()
 soundQueue.qualityOfService = QualityOfService.background 
 soundQueue.addOperation{self.buttonClickSound.play()}

我也有类似的问题。我最终使用SKAction来播放短音。

SKAction.playSoundFileNamed("Sounds/Click.wav", waitForCompletion: false)

有关详细信息,请参阅 SKAction 参考。

最新更新