2017-07-04 36 views
0

我目前正在製作一款遊戲,其中您是中間的一艘太空船,並且有敵方船隻向您移動,您必須向他們開槍才能獲勝。節點聯繫時收到錯誤

當我測試遊戲時,我看到當兩艘或兩艘以上的敵方戰艦同時擊中玩家船時,我收到了一個錯誤。我不確定是否這是導致錯誤的原因,但是當我測試它時,它看起來像是這樣。

我製作了遊戲,以便每當敵方玩家觸摸玩家時,遊戲就結束並且調用一個函數來改變遊戲場景。這是錯誤被調用的地方,只要場景即將改變。

「致命錯誤:意外發現零而展開的可選值」

這裏是爲didBegin代碼(聯繫人:SKPhysicsContact)

func didBegin(_ contact: SKPhysicsContact) { 

    var BodyOne = SKPhysicsBody() 
    var BodyTwo = SKPhysicsBody() 


    if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask{ 
     BodyOne = contact.bodyA 
     BodyTwo = contact.bodyB 
       } 
    else{ 
     BodyOne = contact.bodyB 
     BodyTwo = contact.bodyA 
    } 


    //SHIPS TOUCH EACH OTHER CHECK 
    if BodyOne.categoryBitMask == NumberingPhysics.SpaceShip && BodyTwo.categoryBitMask == NumberingPhysics.LeftV{ 



     GameOver1() 

     BodyTwo.node?.removeFromParent() 
     BodyOne.node?.removeFromParent() 

    } 

    if BodyOne.categoryBitMask == NumberingPhysics.SpaceShip && BodyTwo.categoryBitMask == NumberingPhysics.RightV{ 

     GameOver1() 
     BodyOne.node?.removeFromParent() 
     BodyTwo.node?.removeFromParent() 


     //more code is under here 

    } 

,這裏是遊戲改變場景的代碼。 (當1個敵接觸的球員,但似乎並沒有在2個或更多品牌與球員接觸其作品)

func GameOver1(){ 

    ButtonAudioPlayer.stop() 
    removeAllChildren() 
    removeAllActions() 
    let scene = GameOver(size: self.size) 
    let sKView = self.view! as SKView  // <----- error shows here 
    sKView.ignoresSiblingOrder = true 
    scene.scaleMode = .aspectFill 
    sKView.presentScene(scene) 


} 

有人可以幫我解決這個問題。

+0

我們不知道你在哪裏打電話GameOver1。如果你在場景中調用它,它可能會崩潰。 –

+1

多個聯繫人可能發生在兩個不同對象之間的一幀中,你太早殺死你的精靈 – Knight0fDragon

+1

[SpriteKit遊戲在檢測到兩個SKPhysicsContacts時崩潰]的可能重複(https://stackoverflow.com/questions/43058602/spritekit-game - 當兩個skphysicscontacts被檢測到時崩潰) – Knight0fDragon

回答

2

您的視圖對象爲零,如果您在活動場景內定義GameOver1,則這是特殊的。將您的GameOver1功能移到您的主場景,並且應該解決問題。或者,您可以創建一個全局變量並將其分配給GameViewController中的初始SKView對象。這不是最佳做法,但它會起作用。

var gView = SKView() 

class GameViewController: UIViewController { 
    // Stuff.. 

    if let view = self.view as! SKView? { 
     gView = view 

此外,此代碼中還有其他潛在的崩潰問題。

由於KOD在評論中表示,多個聯繫人可能發生在1幀..但你正在查殺節點(因此pb),這意味着計劃的.didBegin將發現nil或其他一些錯誤和崩潰。

更好的方法是在物理步驟後標記要移除的節點 - 一旦安全處理聯繫人。

一套自己的口罩,一些高數而不是取消它的:

var nodesToKill = SKNode() 

override func didBeginContact(/*prams*/) { 
    // Stuff... 

    BodyB.node!.categoryBitMask = 35 // Or some other number so as 
            // to not trigger another contact. 
    BodyB.node!.moveToParent(nodesToKill) //moves the node off the scene entirely 
} 

override func didSimulatePhysics(/*prams*/) { 

    nodesToKill.removeAllChildren() // or do nodesToKill = SKNode() and let ARC take care of it for you 
} 

此外,你可能想將所有的節點去除的東西收到主叫GAMEOVER,因爲這可能會導致問題,以及與努力做與不再存在的節點的東西。

解決此一個有些做作的方式(如果上述不工作)是這樣的:

var flag_shouldGameOver = false 

override func didFinishUpdate() { 
    if flag_shouldGameOver == true { 
    flag_shouldGameOver = false 
    GameOver1() 
    } 
} 
+1

已更新,以避免陣列,使其保持在Sprite Kit功能,並從場景中刪除節點,而無零崩潰 – Knight0fDragon

+0

@Fluidity你能告訴我,如果函數是在另一個遊戲中定義的,我應該如何調用GameOver1()函數現場?謝謝 –

+0

@AlexMerlin你沒有。我沒有看到你的觀點是如何由提出的場景調用。 – Fluidity