2016-08-15 31 views
0

我正在構建我的SpriteKit遊戲中的PauseButton類,並且我想在激活時爲GameScene繪製標籤。但是,我需要在didMoveToView之外實例化按鈕(在GameScene之前),以便我可以從touchBegan方法更「全局」地訪問它。將當前的GameScene實例傳遞到GameScene中調用的類中

let pauseButton = PauseButton(theTexture: pauseButtonTexture,gameScene:GameScene) 
override func didMoveToView(view: SKView) { 

理想我想能夠通過內didMoveToView實例它的視圖中的通過,但截至目前,我不知道如何做到這一點,還從現場的其餘部分進行訪問。也就是說,是否有一種方法可以通過我正在使用的當前GameScene實例,以便我可以在我的按鈕類的方法內部執行類似gameScene.addchild(label)的操作?我找不到任何有用的東西,所以任何幫助都會很棒!

+0

如果您從GameScene方法中傳遞GameScene,請使用'self'。 –

+0

@phillipMills什麼是參數類型?當我在GameScene中的'didMoveToView'之前調用'let pauseButton = PauseButton(theTexture:pauseButtonTexture,gameScene:self)'時,我得到錯誤'無法將值類型的NSobject - >() - > GameScene轉換爲期望的參數類型GameScene'。 init看起來像:'init(theTexture:SKTexture,gameScene:GameScene){'。謝謝! – Sam

+0

這似乎是說你沒有在GameScene方法中調用它。 –

回答

1

你基本上可以做到這兩點。

1)只需創建屬性這樣

var pauseButton: PauseButton! 

,比實例它didMoveToView像這樣。

override func didMoveToView(view: SKView) { 
    pauseButton = PauseButton(theTexture: pauseButtonTexture,gameScene: self) 
    addChild(pauseButton) 
} 

2)使用延遲實例化,所以你可以做你試圖做的最初。

懶惰的VAR在最簡單的形式可以讓你用自己沒有做第1步

lazy var pauseButton: PauseButton = PauseButton(theTexture: pauseButtonTexture,gameScene: self) 

override func didMoveToView(view: SKView) { 

你甚至可以做到這一點,像這樣所有在同一地點添加此按鈕的更多特性。

lazy var pauseButton: PauseButton = { 
     let button = PauseButton(theTexture: pauseButtonTexture,gameScene: self) 
     button.zPosition = 200 
     button.position = CGPoint(x: self.frame.midX, y: self.frame.midY) 
     button.alpha = 0.5 

     return button 
}() 

override func didMoveToView(view: SKView) { 
     addChild(pauseButton) 
} 

記住每個SKNode/SKSpriteNode等都有一個場景屬性。如果你的按鈕類是SKNode/SKSpriteNode的子類,那麼你可以獲取其場景屬性,並使用「as」運算符來獲得對GameScene的引用,而不用傳入初始化方法中的場景。

e.g

class GameScene: SKScene { 

     lazy var pauseButton: PauseButton = PauseButton(theTexture: pauseButtonTexture,gameScene: self) 

     var someBool = false 

     override func didMoveToView(view: SKView) { 
      addChild(pauseButton) 
      pauseButton.loadPausedLabel() 
     } 

     func someMethod() { 

     }  
} 

class PauseButton: SKSpriteNode { 

     func loadPauseLabel() { 

      // Way 1, reference to current scene but not to specific class 

      guard let scene = scene else { return } 
      // Scene property is optional and is nil until button is added to a Scene so add the guard check. 


      scene.someBool = true  // NOT WORKING 
      scene.someMethod()   // NOT WORKING 

      let label = SKLabelNode(... 
      scene.addChild(label)  // WORKING 

      // Way 2, use "as" to cast to specific scene (e.g GameScene) so you can call properties/methods on it. This is the same as passing GameScene in the init method. 

      guard let gameScene = scene as? GameScene else { return } 
      // Scene property is optional and is nil until button is added to a Scene so add the guard check. 
      // The button must be added to the scene you are trying the as? cast with, in this example GameScene. 


      gameScene.someBool = true  // WORKING 
      gameScene.someMethod()   // WORKING 

      let label = SKLabelNode(... 
      gameScene.addChild(label)  // WORKING 
     } 
} 

有一個小竅門,我不會在暫停按鈕子類中添加的暫停標籤,我會從場景它的自我內或從暫停菜單子類中添加它。 另外我不會繼承每個按鈕,我會創建一個可用於遊戲中所有按鈕的類。您可以創建一個帶有按鈕名稱的枚舉,並將它傳遞給init方法,以在按下按鈕時區分它們。

你的按鈕子類只能處理動畫,紋理等。你可以看看蘋果遊戲DemoBots的例子。

希望這會有所幫助

+0

我只是回顧這個問題,想知道你是否可以使用'var pauseButton:PauseButton!'解釋?我知道它與可選項有關,但我沒有從概念上完全理解它們。在'PauseButton'之後寫一個'!'或'''有什麼區別? – Sam

+1

當然,可能需要將其分成2條評論。基本上!意味着你正在展開var pauseButton屬性。因此,當你在DidMoveToView中實例化它時,你只需要編寫像pauseButton.position,pauseButton.zPosition這樣的東西。你基本上告訴編譯器,pauseButton在那裏,所以我們很酷。現在,如果你想在實例化它之前嘗試使用pauseButton來做些事情,那麼你將會崩潰,因爲你打破了那個說pauseButton總是存在的交易(!)。 – crashoverride777

+1

另一方面,如果你使用?你告訴編譯器,嘿這個暫停按鈕在那裏,或者可能不在那裏。你會比需要寫在didMoveToView東西像這樣,暫停按鈕?.POSITION,暫停按鈕?.zPosition等。這樣,如果你忘了初始化它在DidMoveToView,你不會得到一個崩潰試圖訪問了var暫停按鈕屬性以後,例如touchesMethod。這對於類型安全來說非常方便。想象一下,您還需要創建一些特殊的提升按鈕,僅在特殊場合顯示。使用 ?將使您的代碼更安全,防止出錯。 – crashoverride777

相關問題