2016-03-01 78 views
1

點擊節點時我想要發出聲音。 目前的代碼是:在spritekit swift中點擊節點時聲音不會播放

let sndButtonClick = SKAction.playSoundFileNamed("button_click.wav", waitForCompletion: false) 

,並從觸摸開始

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { 


    for touches: AnyObject in touches { 


     let location = touches.locationInNode(self) 
     if playButton.containsPoint(location) { 
      playButton.runAction(sndButtonClick) 
      playButton.removeFromParent() 

      let nextScene = GamePlayMode(size: self.scene!.size) 
      nextScene.scaleMode = self.scaleMode 
      self.view?.presentScene(nextScene) 
     } 
} 

我做同樣的事情在gameplaymode兩個節點的碰撞和它的作品,但在主菜單中這是行不通的!

我試圖

self.runAction(sndButtonClick) 

然後

playbutton.runAction(sndButtonClick) 

既沒有工作

+1

我懷疑你的問題是在下一行; 'playButton.removeFromParent'。這將刪除該節點並取消其操作。當一個實驗改變劇本的'waitForCompletion'爲'true'。 –

+0

@PriceRingo waitForCompletion參數意味着動作的持續時間將與音頻播放的長度相同,但仍然不會因爲runAction方法的作用而執行動作。我在我的回答中描述了這一點。 – Whirlwind

回答

3

爲什麼運行上的按鈕聲音動作不起作用?

這是從文檔:與相關聯的

一個SKAction對象是受在 場景(SKScene)的節點執行的動作...當場景處理其節點,動作節點被評估。

表示僅當節點被添加到場景時,節點的動作纔會運行。所以,這沒有任何影響:

playButton.runAction(sndButtonClick) 
playButton.removeFromParent() 

,因爲您已刪除從場景的按鍵和操作時,應執行它不會出現在下一幀。這就是runAction方法的工作方式:

向節點執行的動作列表添加一個動作...下一次處理場景的動畫循環時處理新動作。

而且,因爲你立即調用presentScene會有反正沒有下架,這樣即使你刪除removeFromParent語句,聲音將無法工作,因爲沒有下一幀。

爲什麼在場景上運行聲音操作不起作用?

self.runAction(sndButtonClick)將無法​​正常工作,因爲您正在立即進行轉換而無需等待執行排隊操作的下一幀(如上所述)。

解決該問題

要播放的聲音轉換之前,你必須等待下一幀,你可以這樣做:

runAction(sndButtonClick, completion: { 
    self.view?.presentScene(nextScene) 
}) 

let block = SKAction.runBlock({ 
    self.view?.presentScene(nextScene) 
}) 

runAction(SKAction.sequence([sndButtonClick, block])) 

防止泄漏:

考慮使用捕捉自我,以避免可能強引用循環需要的時候,這樣的塊內捕獲列表:

let block = SKAction.runBlock({ 
    [unowned self] in 
    //use self here 
}) 

在你的這種特殊情況下,它應該是安全的去無捕獲列表,因爲場景沒有強烈的參考塊。只有塊對場景有強烈的引用,但塊執行後,由於沒有保留塊(沒有強引用),它將被釋放,因此場景可以正確釋放。但是,如果該塊被聲明爲屬性,或者執行該塊的動作無限運行(使用repeateActionForever方法重複某個序列),那麼您肯定會有泄漏。

你應該總是重寫場景的deinit以查看發生了什麼(如果它沒有被調用,保留場景並導致泄漏)。

+0

非常感謝您提供豐富的答案!問題解決了! – prival

+1

@prival沒問題:)很高興幫助。作爲補充,如果你有一個場景的轉場在實際轉場發生之前有延遲,例如。 'view?.presentScene(nextScene,transition:SKTransition.fadeWithDuration(someDuration))',聲音也會起作用。當然,只要你在場景本身或者添加到場景的節點上運行聲音動作。 – Whirlwind