2017-03-27 11 views
1

シンプルなスプライトキットゲームを作成する。そこには、ボタンライブラリに触れたような音などがあります。AVFoundationサウンドライブラリ。しかし、これに問題があります。いずれのボタンを押すとフレームレートが常に下がります。しかし、私がすべての音を消しても、遅れはありません。私はプリロードすべての私のサウンドにGameAudio.shared.setupSounds()を呼び出す私のGameViewControllerで私のspritekitゲームの遅れを理解できませんか?

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() 
    } 
} 

:ここに私のコードです。

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") 
    } 
} 

私はゲーム内のすべての行動に対してstruct Actionsを使用します。私はbuttonTouchedAction()を持っています、私は別のノードでそれを使用します。私は1つの "再生"ボタンで私のメニューからいくつかのコードを入れました。たとえば、私はゲームでゲームを実行し、メニューノードを表示し、数秒待ってからボタンをタップすると、フレームレートが低下した後、1秒後にラグがあり、シーンがゲームシーンに変化します。

+0

ボタンが「ヒット」したときに実行されるコードを投稿できますか? – Stoyan

+0

ストイヤンを終えました。追加コードで編集。 –

+0

私のサウンドに4つの 'AVAudioPlayer()'を使うのではなく、 'GameAudio'に悪いコードの実装がありますか?これは大丈夫ですか? –

答えて

1

あなたが(代わりにSpriteKit'sサウンドアクションの)AVAudioPlayerを使用する場合は、その動作があなたの視覚的なもののすべてが行くメインスレッドと干渉しないように、音がバックグラウンドスレッドで再生させる必要があります。

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

しかし、ゲームがバックグラウンドになると、私は音を演奏したくありません。 –

+1

@NurassylNuridin、彼はバックグラウンドスレッドを意味します。これは、バックグラウンドでのアプリケーションとは異なります。あなたのアプリは通常、気づかずにいくつかのスレッドで動作します。たとえば、SKActionsのほとんどは別のスレッドで実行されます。バックグラウンドスレッドを使用すると、タイムクリティカルでないコードと、FPSが依存するコードとを区別するのに役立ちます。しかし、私がすでに指摘したように、私は、音を鳴らすのではなくシーンを切り替えることに関連していると考えています。私は、例えばAVAudioPlayersを設定するのと比べてサウンドを再生することはあまりにも高価ではないと信じています。 – Stoyan

+0

アプリケーションがアクティブではなくなったときにゲームが鳴ります。あなたのAVSessionによって制御されます。バックグラウンドスレッド(主に古いiPads)でAVAudioPlayerを再生する前に、私自身のゲームで短期間のレンダリングを行っていましたので、同じ問題が発生した場合に備えて試してみるべきです。 –

1

私にも同様の問題がありました。私は短い音を再生するためにSKActionを使用して終了しました。

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

詳細についてはSKAction referenceを参照してください。

+0

私はこれを試しましたが、私は[これ](http://stackoverflow.com/questions/42874601/my-app-crashes-because-of-unfinished-sounds-in-my-sprite-kit-game)を持っていました。 ) 問題。 –

関連する問題