2017-12-26 175 views
6

Poniżej znajduje się moja klasa "Floor.swift", poniżej której znajduje się po prostu garść ścian. Mam obiekty przychodzące z góry ekranu i gdy zderzają się Piętro i SKSpriteNodes, chciałbym, aby usunięto SKSpriteNode. Poniżej znajduje się moja klasa Floor.Kolizja SKPhysicsBody nie działa

import Foundation 
import SpriteKit 

class Floor: SKNode { 
    override init() { 
     super.init() 

     let leftWall = SKSpriteNode(color: UIColor.clear, size: CGSize(width: 5, height: 50)) 
     leftWall.position = CGPoint(x: 0, y: 50) 
     leftWall.physicsBody = SKPhysicsBody(rectangleOf: leftWall.size) 
     leftWall.physicsBody!.isDynamic = false 
     self.addChild(leftWall) 

     let rightWall = SKSpriteNode(color: UIColor.clear, size: CGSize(width: 5, height: 50)) 
     rightWall.position = CGPoint(x: 375, y: 50) 
     rightWall.physicsBody = SKPhysicsBody(rectangleOf: rightWall.size) 
     rightWall.physicsBody!.isDynamic = false 
     self.addChild(rightWall) 

     let bottomWall = SKSpriteNode(color: UIColor.clear, size: CGSize(width: 500, height: 10)) 
     bottomWall.position = CGPoint(x: 150, y: -5) 
     bottomWall.physicsBody = SKPhysicsBody(rectangleOf: bottomWall.size) 
     bottomWall.physicsBody!.isDynamic = false 
     self.addChild(bottomWall) 

     self.physicsBody = SKPhysicsBody(bodies: [leftWall.physicsBody!, rightWall.physicsBody!, bottomWall.physicsBody!]) 

     self.physicsBody?.categoryBitMask = floorCategory 
     self.physicsBody?.contactTestBitMask = nailDropCategory | pointCategory | lifeCategory 
     self.physicsBody?.collisionBitMask = balloonCategory 
    } 

    required init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemted") 
    } 
} 

klasa GameScene pod "func didBegin (_ kontakt: SKPhysicsContact)" Napisałem:

func didBegin(_ contact: SKPhysicsContact) {   
     if (contact.bodyA.categoryBitMask == nailDropCategory | pointCategory | lifeCategory) && (contact.bodyB.categoryBitMask == floorCategory) { 
      // contact.bodyB.node!.removeFromParent() 
      print("COLLISION") 
     } 
} 

Jak widać, w mojej klasie I piętro ustawić obiekt jako „self.physicsBody = SKPhysicsBody (ciała :) "z całym moim SKSpriteNode. Ale z jakiegoś powodu nie dostaję żadnego wykrycia, co jest takiego. Zrobiłem moją klasę "Floor" jako "contactTestBitMask" dla każdej klasy z mojej objectCategory, pointCategory, lifeCategory. To był problem, na którym utknąłem przez chwilę, jakieś pomysły?

Aktualizacja:

więc używam tego kodu poniżej teraz i to działa! Jedynym problemem jest to, że domyślnym przypadkiem jest usunięcie mojej "balloonCategory" również i nie chcę tego robić. Jak mogę go zignorować tylko w tej kategorii, ale także działać jako ściana balonu?

func didBegin(_ contact: SKPhysicsContact) { 
     let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask 

     switch contactMask { 
     case balloonCategory | nailDropCategory: 
      print("nailDrop and balloon have contacted.") 
      contact.bodyB.node!.removeFromParent() 
      self.run(SKAction.playSoundFileNamed("lostlifesound.mp3", waitForCompletion:false)) 
      lifeLost -= 1 
     case balloonCategory | pointCategory: 
      print("point and balloon have contacted.") 
      contact.bodyB.node!.removeFromParent() 
      totalPoints += 2 
      self.run(SKAction.playSoundFileNamed("pointsound.mp3", waitForCompletion:false)) 
     case balloonCategory | lifeCategory: 
      print("life and balloon have contacted.") 
      contact.bodyB.node!.removeFromParent() 
      lifeLost += 1 
      self.run(SKAction.playSoundFileNamed("pointsound.mp3", waitForCompletion:false)) 
     default:    
      contact.bodyB.node!.removeFromParent() 
      print("Removed \(String(describing: contact.bodyB.node!.name))") 
     } 
    } 
+0

NailDropCategory? pointCategory? lifeCategory? Nikt oprócz Ciebie nie wie, jak definiujesz swoje maski bitowe. –

+0

Cóż, zdefiniowałem to na wszystkich moich innych klasach i wszystkich innych zdarzeniach, więc jestem po prostu zgubiony. Lol – Dewan

+1

Jeśli fizyka działa już w twoim projekcie, wydaje się, że to powinno działać. Czy możesz odtworzyć ten problem w przykładowym projekcie i udostępnić go na Github? Wygląda na to, że rozwiązanie może pochodzić z debugowania. – peacetype

Odpowiedz

5

Brzmi jak chcesz korzystać z przypisanie nazwy do wszystkich typów obiektów, tak jak poniżej:

class Balloon: SKSpriteNode { 
    init() { 
     super.init(texture: nil, color: .blue, size: CGSize(width: 50, height: 50)) 
     self.name = "balloon" 
    } 
} 

Teraz, kiedy dokonać wyboru w przełączniku można zweryfikować tożsamość obiektów przed podjęciem decyzji, aby usunąć im. Zobacz zmianę, którą wprowadziłem w domyślnym przypadku w Twojej instrukcji switch, poniżej. W ten sposób węzeł nie zostanie usunięty, jeśli jest to dymek. Zderzenia fizyki będą nadal działać.

func didBegin(_ contact: SKPhysicsContact) { 
    let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask 

    switch contactMask { 
    case balloonCategory | nailDropCategory: 
     print("nailDrop and balloon have contacted.") 
     contact.bodyB.node!.removeFromParent() 
     self.run(SKAction.playSoundFileNamed("lostlifesound.mp3", waitForCompletion:false)) 
     lifeLost -= 1 
    case balloonCategory | pointCategory: 
     print("point and balloon have contacted.") 
     contact.bodyB.node!.removeFromParent() 
     totalPoints += 2 
     self.run(SKAction.playSoundFileNamed("pointsound.mp3", waitForCompletion:false)) 
    case balloonCategory | lifeCategory: 
     print("life and balloon have contacted.") 
     contact.bodyB.node!.removeFromParent() 
     lifeLost += 1 
     self.run(SKAction.playSoundFileNamed("pointsound.mp3", waitForCompletion:false)) 
    default: 
     if contact.bodyB.node!.name == "balloon" { 
      print("Balloon collided but we will not remove it.") 
      return 
     } else { 
      contact.bodyB.node!.removeFromParent() 
      print("Removed \(String(describing: contact.bodyB.node!.name))") 
    } 
} 
+0

Koleś Naprawdę doceniam twoją pomoc! Jesteś błogosławiącym braminem i mam nadzieję, że masz wspaniały nowy rok! Jeszcze raz bardzo dziękuję – Dewan

+1

To samo dla Ciebie i powodzenia w grze! – peacetype

+1

Dzięki! Ostatnie pytanie: jaka jest twoja ulubiona sieć reklamowa na iOS? – Dewan

1

Nie można zagwarantować, że węzeł B jest podłogą i jest węzłem A naprawdę nailDropCategory | pointCategory | lifeCategory?

Jestem zakładając, że naildDrop, point i life są 3 obiekty, które chcesz być powiadomiony, gdy ktoś dotyka floor, więc spróbuj Strukturyzacji didBegin(contact:) tak:

func didBegin(_ contact: SKPhysicsContact) { 
    print("didBeginContact entered for \(String(describing: contact.bodyA.node!.name)) and \(String(describing: contact.bodyB.node!.name))") 

    let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask 

    switch contactMask { 
    case nailDropCategory | FloorCategory: 
     print("nailDrop and floor have contacted.") 
    case pointCategory | FloorCategory: 
     print("point and floor have contacted.") 
    case lifeCategory | FloorCategory: 
     print("life and floor have contacted.") 
    default: 
     print("Undetected collision occurred") 
    } 
} 

Czy rzeczywiście stworzył obiekt z klasy Floor?

+0

Mówi, że "didBeginContact wprowadzono dla zer i nilów" i zwracając "default:" w przełączniku. Ponadto, wykonanie linii "self.physicsBody = SKPhysicsBody (body: [leftWall.physicsBody !, rightWall.physicsBody !, bottomWall.physicsBody!])" Pokrywa się z istniejącym fizycznym elementem i powoduje pewne problemy. Nie jestem pewien, co się dzieje, ponieważ to działało wcześniej, więc jestem kompletnie zagubiony. – Dewan

+0

Wiemy, że coś się z tobą skontaktowało - upewnij się, że każdy węzeł w twojej scenie ma imię, wtedy dowiesz się, co się zderzyło. Nie jestem pewien, co masz na myśli, kiedy mówisz, że ja, physicsBody ... pokrywa się z istniejącym ciałem fizyki, ponieważ zgodnie z twoim kodem, obiekt Floor nie ma istniejącego ciała fizycznego. –

+0

Tablica SKPhysicsBody zawierająca wszystkie obiekty wraz z linią kodu "bottomWall.physicsBody = SKPhysicsBody (rectangleOf: bottomWall.size)", którą również zrobiłem dla leftWall i rightWall. Dosłownie tworzę podwójne Ciało Fizyki i nakładają się, więc w tym momencie nie jestem pewien co się dzieje. To jest stresujące. – Dewan