2017-07-04 14 views
0

Ich mache gerade ein Spiel, in dem du ein Raumschiff in der Mitte bist und feindliche Schiffe sich dir nähern und du musst auf sie schießen, um zu gewinnen.Einen Fehler empfangen, wenn Knoten Kontakt herstellen

Während ich das Spiel testete, sah ich, dass ich einen Fehler erhalte, wenn (wie es scheint) zwei oder mehr feindliche Schiffe das Spielerschiff gleichzeitig treffen. Ich bin mir nicht sicher, ob das den Fehler verursacht, aber es sieht so aus, wenn ich es teste.

Ich habe das Spiel so gemacht, dass, wenn feindliche Spieler den Spieler berühren, das Spiel endet und eine Funktion aufgerufen wird, um die Spielszene zu ändern. Hier wird der Fehler immer dann aufgerufen, wenn sich die Szene ändert.

„fatalen Fehler: unerwartet gefunden, gleich Null, während ein optionaler Wert auspackt“

hier ist der Code für die didBegin (Kontakt: 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 

    } 

Und hier ist der Code des Spiels zu ändern Szene . (Das funktioniert, wenn ein Feind die Spieler berührt, aber scheint nicht zu, wenn zwei oder mehr Marken mit dem Spieler in Verbindung)

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) 


} 

Kann jemand bitte helfen Sie mir, dieses Problem zu beheben.

+0

Wir wissen nicht, wo Sie GameOver1 anrufen. Wenn Sie es innerhalb einer Szene aufrufen, kann es abstürzen. –

+1

Mehrere Kontakte können in einem Frame zwischen zwei verschiedenen Objekten auftreten, Sie werden Ihr Sprite zu früh töten – Knight0fDragon

+1

Mögliche Duplikate von [SpriteKit Spiel stürzt ab, wenn zwei SKPhysicsContacts erkannt werden] (https://stackoverflow.com/questions/43058602/spritekit-game -crashes-when-two-skphysic Contacts-werden erkannt – Knight0fDragon

Antwort

2

Ihr View-Objekt ist nil, was besonders ist, wenn Sie GameOver1 innerhalb der aktiven Szene definieren. Verschieben Sie Ihre GameOver1-Funktion in Ihre Hauptszene, und das sollte das Problem beheben.

Oder Sie könnten eine globale Variable erstellen und sie dem ursprünglichen SKView-Objekt in Ihrem GameViewController zuweisen. Dies ist keine bewährte Methode, aber es wird funktionieren.

var gView = SKView() 

class GameViewController: UIViewController { 
    // Stuff.. 

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

Sie haben auch andere potenzielle Absturzprobleme in diesem Code.

Wie KOD sagte in Kommentaren mehrere Kontakte können in 1 Rahmen .. aber Sie töten den Knoten (und damit pb) was bedeutet, dass die geplante .didBegin wird nil oder einen anderen Fehler finden und Absturz.

Ein besserer Weg, dies zu tun, ist, den Knoten nach dem Physik-Schritt für die Entfernung zu markieren - sobald Kontakte sicher gehandhabt werden.

Stellen Sie ihre Maske zu einigen High-Nummer, anstatt es zu entfernen:

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 
} 

Auch Sie wahrscheinlich alle von dem Zeug Knoten Entfernen wollen Gameover vor dem Aufruf, wie die Fragen als auch mit dem Versuch verursachen können Mach Sachen mit Knoten, die nicht mehr existieren.

Ein etwas gekünstelt Weg, um dies ist (wenn die oben nicht funktioniert hat) so etwas wie diese:

var flag_shouldGameOver = false 

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

Aktualisiert, um das Array zu vermeiden, behält es in Sprite Kit-Funktionalität und entfernt den Knoten aus der Szene ohne null Absturz – Knight0fDragon

+0

@Fluidity können Sie mir sagen, wie soll ich die GameOver1() -Funktion aufrufen, wenn die Funktion in einem anderen Spiel definiert ist Szene? Danke –

+0

@AlexMerlin youre nicht. Ich sehe nicht, wie deine Sicht null ist, wenn sie von der dargestellten Szene aufgerufen wird. – Fluidity

Verwandte Themen