2016-04-12 7 views
3

Manchmal werden in meinen SpriteKit-Programmen meine Kollisionen und Kontakte (unter Verwendung von SKPhysicsBody) nicht wie erwartet ausgelöst oder funktionieren. Ich denke, ich habe alles eingerichtet, was ich brauche, aber ich bekomme immer noch nicht die richtigen Interaktionen. Wie kann ich leicht überprüfen, was mit was kollidiert und welche Körper aufgebaut sind, um Kontakte zu generieren?iOS SpriteKit - Kollisionen und Kontakte funktionieren nicht wie erwartet

+0

Diese Art von Fragen sind tatsächlich geeignet für [Code Review] (http://codereview.stackexchange.com/) – Whirlwind

+3

Dies ist nur für Code Review geeignet, wenn der Code wie erwartet funktioniert und wenn das OP eine Überprüfung möchte. .. Vom Ton dieser Frage will er keine Überprüfung, er will eine Fehlerüberprüfung seines Codes ... –

+0

Eigentlich möchte ich nicht, dass mein Code überprüft wird, da ich denke, dass es funktioniert, aber ich habe versucht, etwas zu schreiben, das Leuten mit Kollisions-/Kontaktproblemen helfen würde. Vielleicht hätte ich eine Frage stellen sollen, dass ich Probleme habe und dann meine CheckPhysik als Antwort funktioniert? –

Antwort

4

Um diese Art von Problemen zu diagnostizieren, habe ich eine Funktion geschrieben, die von überall aufgerufen werden kann und die aktuelle Szene analysiert und eine Liste der Knoten mit Kollision mit anderen Kollisionen und Kollisionen meiner Szene erstellt zum.

Die Funktion ist Stand-alone und muss nicht über die Knoten in der Szene informiert werden.

Die Funktion ist wie folgt:

  //MARK: - Analyse the collision/contact set up. 
    func checkPhysics() { 

     // Create an array of all the nodes with physicsBodies 
     var physicsNodes = [SKNode]() 

     //Get all physics bodies 
     enumerateChildNodesWithName("//.") { node, _ in 
      if let _ = node.physicsBody { 
       physicsNodes.append(node) 
      } else { 
       print("\(node.name) does not have a physics body so cannot collide or be involved in contacts.") 
      } 
     } 

//For each node, check it's category against every other node's collion and contctTest bit mask 
     for node in physicsNodes { 
      let category = node.physicsBody!.categoryBitMask 
      // Identify the node by its category if the name is blank 
      let name = node.name != nil ? node.name : "Category \(category)" 
      let collisionMask = node.physicsBody!.collisionBitMask 
      let contactMask = node.physicsBody!.contactTestBitMask 

      // If all bits of the collisonmask set, just say it collides with everything. 
      if collisionMask == UInt32.max { 
       print("\(name) collides with everything") 
      } 

      for otherNode in physicsNodes { 
       if (node != otherNode) && (node.physicsBody?.dynamic == true) { 
        let otherCategory = otherNode.physicsBody!.categoryBitMask 
        // Identify the node by its category if the name is blank 
        let otherName = otherNode.name != nil ? otherNode.name : "Category \(otherCategory)" 

        // If the collisonmask and category match, they will collide 
        if ((collisionMask & otherCategory) != 0) && (collisionMask != UInt32.max) { 
         print("\(name) collides with \(otherName)") 
        } 
        // If the contactMAsk and category match, they will contact 
        if (contactMask & otherCategory) != 0 {print("\(name) notifies when contacting \(otherName)")} 
       } 
      } 
     } 
    } 

Sie müssen auch diese 3 Dinge überprüfen:

  1. die Szene muss ein SKPhysicsContactDelegate
  2. sein Sie setzen müssen physicsWorld.contactDelegate = self
  3. Sie müssen eine der optionalen Methoden implementieren:

didBeginContact

didEndcontact

Die Funktion aufgerufen werden soll, wenn Sie alle Ihre Bilder eingerichtet haben - in der Regel am Ende der didMoveToView Werke:

checkPhysics() 

Als ich Rufen Sie diese Funktion am Ende meiner didMoveToView in meiner Praxis Swift-Projekt, bekomme ich folgende Ausgabe:

Optional ("shape_blueSquare") kollidiert mit Optional ("Kategorie 2147483648") Optional ("shape_blueSquare") kollidiert mit Optional ("shape_redCircle") Optional ("shape_blueSquare") kollidiert mit Optional ("shape_purpleSquare" Optional) ("shape_blueSquare") kollidiert mit Optional ("shape_yellowTriangle") Optional ("shape_redCircle") kollidiert mit Optional ("Kategorie 2147483648") Optional ("shape_redCircle") kollidiert mit Optional ("shape_blueSquare") Optional ("shape_redCircle") benachrichtigt bei der Kontaktaufnahme Optional ("shape_purpleSquare") Optional ("shape_redCircle") kollidiert mit Option al ("shape_yellowTriangle") Optional ("shape_redCircle") benachrichtigt, wenn Optional kontaktieren ("shape_yellowTriangle") Optional ("shape_purpleSquare") kollidiert mit Optional ("Kategorie 2147483648") Optional ("shape_purpleSquare") kollidiert mit Optional ("shape_yellowTriangle") Optional ("shape_yellowTriangle") kollidiert mit allem, was didBeginContact eingegeben für Optional ("shape_purpleSquare") und optional ("shape_redCircle") didBeginContact eingetragen für Optional ("shape_purpleSquare") und Optional ("shape_redCircle") didBeginContact eingegeben für Optional ("shape_yellowTriangle") und Optional ("shape_redCircle")

Kategorie 2147483648 ist meine Kantengrenze und hat keinen Namen. Ich gab ihm diese Kategorie, um seine Kollision zu entsprechenBitMask

Bitte fühlen Sie sich frei, diese Funktion zu versuchen und lassen Sie mich wissen, wenn es nützlich ist oder wenn es irgendwelche Situationen gibt, die es nicht behandelt.

+1

Dies ist ein github wertvolles Werkzeug! – Confused