2015-12-31 48 views
0

我發現它比較難以形成邏輯把我的音樂和SFX開啓和關閉。我的遊戲有各種不同的SKScenes,並且我已經在每個場景中聲明瞭所有音樂等,並且專門針對每個場景播放。但是,我不確定如何在SkScenes之一中編寫音樂和sfx的開關按鈕。我意識到我需要在視圖控制器中聲明所有音樂和sfx,並向每個場景發送通知以通知聲音何時播放。這樣做後,我將如何編寫邏輯來打開和關閉?開啓和關閉音樂/ SFX雪碧套件

+0

爲什麼你需要聲明的音樂在視圖控制器?只要保持跟蹤你所有的音頻節點的數組,當你需要靜音的聲音,暫停所有節點,那麼當你在玩音效它包裝在一個如果靜音不玩檢查 – Knight0fDragon

回答

1

正如我上面的網友說,你沒有把你的音樂到視圖控制器。 我這樣做的方式如下。我把所有的音樂都放到了一個單獨的幫助器類中,這有助於保持viewController的清潔。

一個簡單的版本,可以很容易地擴展爲多音軌可能看起來像這樣

import AVFoundation 

class Music: NSObject { 

// MARK: - Static Properties 

/// Shared instance 
static let sharedInstance = Music() 

/// URLs 
private struct URL { 
    static let avPlayer1 = "MenuMusic" // file name 
    static let avPlayer2 = "GameMusic" // file name 
    static let avPlayerExtension = "mp3" 
} 

/// Keys 
private struct Key { 
    static let muted = "MusicMuteState" 
} 

// MARK: - Properties 

/// Local defaults 
private let localDefaults = NSUserDefaults.standardUserDefaults() 

/// Players 
private var avPlayer1: AVAudioPlayer! 
private var avPlayer2: AVAudioPlayer! 

/// Last played 
private enum LastPlayed { 
    case Nothing 
    case AVPlayer1 
    case AVPlayer2 
} 
private var lastPlayed = LastPlayed.Nothing 

// MARK: - Init 
private override init() { 
    super.init() 
    print("Music helper init") 
    prepareAVPlayer1() 
    prepareAVPlayer2() 

    if isMuted() { 
     mute() 
    } 
} 

// MARK: - User Methods 

/// Play 
func playMenu() { 
    lastPlayed = .AVPlayer1 
    avPlayer1.play() 
} 

func playGame() { 
    lastPlayed = .AVPlayer2 
    avPlayer2.play() 
} 

/// Pause (eg PauseMenu, Advertising etc) 
func pause() { 
    avPlayer1.pause() 
    avPlayer2.pause() 
} 

/// Resume 
func resume() { 
    switch lastPlayed { 
    case .AVPlayer1: 
     avPlayer1.play() 
    case .AVPlayer2: 
     avPlayer2.play() 
    case .Nothing: 
     break 
    } 
} 

/// Stop and Reset (eg GameOver) 
func stop() { 
    avPlayer1.stop() 
    avPlayer1.currentTime = 0 
    avPlayer1.prepareToPlay() 

    avPlayer2.stop() 
    avPlayer2.currentTime = 0 
    avPlayer2.prepareToPlay() 
} 

/// Mute 
func mute() { 
    avPlayer1.volume = 0 
    avPlayer2.volume = 0 
    localDefaults.setBool(true, forKey: Key.muted) 
} 

/// Unmute 
func unmute() { 
    avPlayer1.volume = 1 
    avPlayer2.volume = 1 
    localDefaults.setBool(false, forKey: Key.muted) 
} 

/// Check mute state 
func isMuted() -> Bool { 
    if localDefaults.boolForKey(Key.muted) { 
     return true 
    } else { 
     return false 
    } 
} 

// MARK: - Private Methods 

/// Prepare player 1 
private func prepareAVPlayer1() { 
    if let avPlayer1URL = NSBundle.mainBundle().URLForResource(URL.avPlayer1, withExtension: URL.avPlayerExtension) { 
     do { 
      avPlayer1 = try AVAudioPlayer(contentsOfURL: avPlayer1URL) 
     } catch { 
      print("Error finding AVAudioPlayer 1 file") 
     } 
    } 
    avPlayer1.delegate = self 
    avPlayer1.numberOfLoops = -1 
    avPlayer1.prepareToPlay() 
} 

/// Prepare player 2 
private func prepareAVPlayer2() { 
    if let avPlayer2URL = NSBundle.mainBundle().URLForResource(URL.avPlayer2, withExtension: URL.avPlayerExtension) { 
     do { 
      avPlayer2 = try AVAudioPlayer(contentsOfURL: avPlayer2URL) 
     } catch { 
      print("Error finding AVAudioPlayer 2 file") 
     } 
    } 
    avPlayer2.delegate = self 
    avPlayer2.numberOfLoops = -1 
    avPlayer2.prepareToPlay() 
} 

您可以初始化助手,像這樣

Music.sharedInstance 

或者調用它的用戶的方法之一時。

現在,當按下靜音按鈕,我叫

Music.sharedInstance.mute() 

Music.sharedInstance.unmute() 

簡單地將音量更改爲0或1,這比試圖暫停/停止音樂更加方便易。 如果您設置了靜音按鈕,您還需要添加支票以查看音樂是否靜音,以便在您的應用啓動時顯示正確的按鈕。只需運行幫手檢查

if Music.sharedInstance.isMuted() { 
    // music is muted, show unmute button 
} else { 
    // music is not muted, show mute button 
} 

現在對於音效,如果您使用AVFoundation其原理相同。如果你使用SKAction.playSound ...比它稍有不同。首先,我還爲我的所有音效創建一個輔助類。在那個幫手中,我創建了一個「mutedSoundEffects」布爾。 現在,如果聲音效果被靜音,我將該布爾設置爲true。 惱人的部分是你必須去所有線路在您的播放SKAction並改變它像這樣

if !SoundEffects.sharedInstance.isMuted() { 
    // play SKAction sound 
} 

希望有所幫助。

GitHubProject: https://github.com/crashoverride777/Swift2-SpriteKit-Music-Helper

+0

非常感謝你的幫助,但是如果這不是太麻煩,你介意在目標c中寫代碼嗎?我對swift不太熟悉,我的應用程序是用目標c寫的。預先感謝你 – RT33

+0

嘿,我很抱歉,但我的客觀c知識是非常基本的。你在哪些部分掙扎? – crashoverride777