2017-01-09 36 views
1

我正在開發一款基於對夫婦SpriteKitSwift的iOS遊戲。從iOS的7.1開始一個節點暫停的場景

我已經在遊戲中實現短的聲音的方式定位是通過使用SKAction.playSoundFileNamed方法是在一個平面層節點執行爲目的特地加入了運行操作:

let SoundsLayerNode = SKNode() 

self.addChild(SoundsLayerNode) 

SoundsLayerNode.runAction(soundXXX) 

它真的很容易通過暫停整個節點(SoundsLayerNode.paused = true)來靜音FX聲音,並再次打開聲音,取消暫停節點(SoundsLayerNode.paused = false

當我試圖在節點已暫停的情況下啓動場景時,會出現問題。裏面的FUNC didMoveToView方法我設置SoundsLayerNode.paused = true但第一Spritekit循環開始後,該節點是自動unpaussed

看來,SpriteKit迫使場景(個體經營)​​後取消暫停結束,其所有後代都因此引發聲音層上不愉快的副作用節點

你知道如何對它進行分類嗎?

由於

+0

嘗試加入這個'runAction(SKAction.runBlock {self.SoundsLayerNode.paused =真})''來didMoveToView' – 0x141E

+0

恐怕也不起作用,因爲該問題後發生第一個渲染循環結束(或第二個循環的開始)。如果我在didMoveToView中運行Action,它會在觸發'unpause'效果之前的第一個-didEvaluateAction方法中執行 – Codediver

回答

0

一種解決方案是運行的節點上的一個SKAction一定量的時間(例如0.1秒鐘)後,暫停播放。

var pauseAction = SKAction.sequence([SKAction.wait(forDuration: 0.1), SKAction.pause()]) 
node.run(pauseAction) 

你可以玩0.1,看看你有多低可以使它仍然工作。

如果不工作,你可以在你GameScene做一個變通這樣的:

var pauseToggle = true 

override func didFinishUpdate() 
    { 
     if(pauseToggle){ 
      SoundsLayerNode.paused = true 
      pauseToggle = false 
     } 
    } 

這是一種做的一個垃圾的方式,但也應該工作。

+0

不幸的是,第一步不起作用 – Codediver

+0

第二個選項仍然失敗。我不知道爲什麼在第一個渲染循環中我無法暫停節點。看起來有必要通過第二個循環。也許我可以嘗試類似於計數器的東西,並在計數器== 2時設置SoundsLayerNode.paused = true。但是我不喜歡這個選項 – Codediver

+0

@Codediver失敗,因爲在節點變得沒有被擱置了嗎?是的,我同意這是一個令人討厭的方式,即使使用布爾值也是如此。如果不知道它,也許還有其他的地方你沒有注意到這個節點。你的GameScene代碼是否足夠短,可以放入你的文章? – MarshallD

0

的代碼是很長,但我想一個簡單的測試GameScene所以你可以,如果我跑了一段時間的應用程序看一看在控制檯中顯示的結果:

內didMoveToView testNode暫停:真正 場景(個體經營)暫停:假

Loop_Update:0 testNode暫停:真 場景(個體經營)暫停:假

Loop_didEvaluateActions:0 testNode暫停:真 場景(個體)暫停:假

Loop_didFinishUpdate:0 testNode暫停:真 場景(個體)暫停:假

Loop_Update:1個 testNode暫停:假 場景(個體)是暫停:假

Loop_didEvaluateActions:1個 testNode暫停:假 場景(個體)暫停:假

Loop_didFinishUpdate:1 testNode已暫停:false 場景(自我)暫停:false

spritekit是否強制場景在第一個渲染循環之後取消暫停本身?

// 
// Test on paused Nodes 
// 

import SpriteKit 


class GameScene: SKScene { 

    let testNode = SKNode() 
    var loopCounter:Int = 0 


    override func didMoveToView(view: SKView) { 

    self.addChild(testNode) 
    testNode.paused = true 

    print ("Inside didMoveToView") 
    print("testNode is paused:",testNode.paused) 
    print("scene(self) is paused:",scene!.paused) 
    print("") 

} 

override func update(currentTime: CFTimeInterval) { 

    print ("Loop_Update:",loopCounter) 
    print("testNode is paused:",testNode.paused) 
    print("scene(self) is paused:",scene!.paused) 
    print("") 

} 

override func didEvaluateActions() { 

    print ("Loop_didEvaluateActions:",loopCounter) 
    print("testNode is paused:",testNode.paused) 
    print("scene(self) is paused:",scene!.paused) 
    print("") 

} 

override func didFinishUpdate() { 

    // This is the last chance to make changes to the scene 

    print ("Loop_didFinishUpdate:",loopCounter) 
    print("testNode is paused:",testNode.paused) 
    print("scene(self) is paused:",scene!.paused) 
    print("") 

    loopCounter=loopCounter+1 

} 

// After didFinishUpdate SKView renders the scene. 
// Does spritekit force the scene to unpause itself here? 

}

+0

根據你在這裏的內容,看起來你是正確的,最終節點變得沒有被暫停。如果在didMoveToView之後有一個方法被調用,那麼我不知道它。最好的解決方案是解決它 - 我有一個想法,涉及一個約0.5秒後被調用一次的SKAction - 你是否希望我將這個添加到我的答案中? – MarshallD

+0

是的,它確實發生在第一個渲染循環的末尾。我希望有人知道原因。請添加你的代碼,這聽起來很有趣,我想評價你的幫助 – Codediver

+0

我更新了答案 – MarshallD