2016-09-21 73 views
1

我注意到這個問題發生在很多人身上。我確保在didMove函數中有self.physicsWorld.contactDelegate = self 但它仍然不起作用。這裏是我的代碼:Spritekit- DidBeginContact不叫

class PoolTableScene: SKScene, SKPhysicsContactDelegate { 

    struct PhysicsCatagory { 

    static let None : UInt32 = 0 //0 
    static let OrangeBall : UInt32 = 0b1 //1 
    static let BlueBall : UInt32 = 0b10 //2 
    static let PokeBall : UInt32 = 0b100 //3 
    static let Border : UInt32 = 0b1000 //4 
    static let All : UInt32 = UInt32.max 

    } 


    let ballPoke = SKSpriteNode(imageNamed:"pokeBall") 
    let ballBlue = SKSpriteNode(imageNamed:"blueBall") 
    let ballOrange = SKSpriteNode(imageNamed: "orangeBall") 
    //var lastTouch: CGPoint? = nil 


    override func didMove(to view: SKView) { 

    self.physicsWorld.contactDelegate = self 

    self.physicsWorld.gravity = CGVector(dx: 0, dy: -9.8) 

    //used to set gravity 


    //creates body for sprite that will lock the objects to a specific area 
    let sceneBody = SKPhysicsBody(edgeLoopFrom: self.frame) 
    sceneBody.friction = 0 //This will make the ball bounce naturally off the edges of the scenBody 
    self.physicsBody = sceneBody // make physics only affect whats in sceneBody - NEED PHYSICS BODY UNLESS IT WON'T BE AFFECTED BY PHYSICS 
    self.physicsBody?.categoryBitMask = PhysicsCatagory.Border 
    self.physicsBody?.collisionBitMask = PhysicsCatagory.BlueBall | PhysicsCatagory.OrangeBall | PhysicsCatagory.PokeBall 
    self.physicsBody?.contactTestBitMask = PhysicsCatagory.None 

    ballPoke.name = "ballPoke" 
    ballPoke.size = CGSize(width: 50, height: 50) 
    ballPoke.anchorPoint = CGPoint(x:0.5, y:0.5) 
    ballPoke.position = CGPoint(x: self.frame.size.width*0.25, y:self.frame.size.height/2) 
    ballPoke.zPosition = 100 
    ballPoke.physicsBody = SKPhysicsBody(circleOfRadius: 25)//need this so the ball can be affected by physics 
    ballPoke.physicsBody?.affectedByGravity = true //ball will be affected by gravity determined by the scene's physics 
    ballPoke.physicsBody?.restitution = 1 // sets bounciness of ball 
    ballPoke.physicsBody?.linearDamping = 0 //used to set how air resistence will affect ball 
    ballPoke.physicsBody?.categoryBitMask = PhysicsCatagory.PokeBall 
    ballPoke.physicsBody?.collisionBitMask = PhysicsCatagory.BlueBall | PhysicsCatagory.Border 
    ballPoke.physicsBody?.contactTestBitMask = PhysicsCatagory.OrangeBall 

    self.addChild(ballPoke) 


    ballBlue.name = "ballBlue" 
    ballBlue.size = CGSize(width: 50, height: 50) 
    ballBlue.anchorPoint = CGPoint(x:0.5, y:0.5) 
    ballBlue.position = CGPoint(x: self.frame.size.width*0.50, y:self.frame.size.height/3) 
    ballBlue.zPosition = 100 
    ballBlue.physicsBody = SKPhysicsBody(circleOfRadius: 25)//need this so the ball can be affected by physics 
    ballBlue.physicsBody?.affectedByGravity = true //ball will be affected by gravity determined by the scene's physics 
    ballBlue.physicsBody?.restitution = 1 // sets bounciness of ball 
    ballBlue.physicsBody?.linearDamping = 0 //used to set how air resistence will affect ball 
    ballBlue.physicsBody?.categoryBitMask = PhysicsCatagory.BlueBall 
    ballBlue.physicsBody?.collisionBitMask = PhysicsCatagory.OrangeBall | PhysicsCatagory.PokeBall | PhysicsCatagory.Border 
    ballBlue.physicsBody?.contactTestBitMask = PhysicsCatagory.None 

    self.addChild(ballBlue) 

    ballOrange.name = "ballOrange" 
    ballOrange.size = CGSize(width: 50, height: 50) 
    ballOrange.anchorPoint = CGPoint(x:0.5, y:0.5) 
    ballOrange.position = CGPoint(x: self.frame.size.width*0.75, y:self.frame.size.height/2) 
    ballOrange.zPosition = 100 
    ballOrange.physicsBody = SKPhysicsBody(circleOfRadius: 25)//need this so the ball can be affected by physics 
    ballOrange.physicsBody?.affectedByGravity = true //ball will be affected by gravity determined by the scene's physics 
    ballOrange.physicsBody?.restitution = 1 // sets bounciness of ball 
    ballOrange.physicsBody?.linearDamping = 0 //used to set how air resistence will affect ball 
    ballOrange.physicsBody?.categoryBitMask = PhysicsCatagory.OrangeBall 
    ballOrange.physicsBody?.collisionBitMask = PhysicsCatagory.BlueBall | PhysicsCatagory.Border 
    ballOrange.physicsBody?.contactTestBitMask = PhysicsCatagory.PokeBall 

    self.addChild(ballOrange) 

    } 

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 

    //Finds the position where user touches screen 
    for touch: AnyObject in touches { 

     let positionOfTouch = touch.location(in: self) 

     //drags ball to where user touches screen 
     let dragBallAction = SKAction.move(to: CGPoint(x: positionOfTouch.x, y: positionOfTouch.y), duration: 0.5) 
     ballOrange.run(dragBallAction) 

    } 

    } 


    func didBeginContact(contact: SKPhysicsContact) { 

    print("contact") 

    var contactBody1: SKPhysicsBody 
    var contactBody2: SKPhysicsBody 

    if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask { 

     contactBody1 = contact.bodyA 
     contactBody2 = contact.bodyB 
    } 
    else// else almost never gets called but still add it to function 

    { 
     contactBody1 = contact.bodyB 
     contactBody2 = contact.bodyA 
    } 

    //this uses the catagories set up in above struct (1 = Square, 2 = Ball) 
    if ((contactBody1.categoryBitMask == 1) && (contactBody2.categoryBitMask == 3)) { 

     //if the ball contact the square, remove the ball 
     contactBody2.node!.removeFromParent() 


    } 


    } 

} 
+0

」仍然不起作用「 - 請更具體一些。你期望什麼,你看到它發生了什麼? – Whirlwind

+0

「我注意到這個問題發生在很多人身上」 - 只有當他們錯過了某些東西時:-) –

+0

'contactBody2.categoryBitMask == 3' <--- ???這不可能是正確的 – Knight0fDragon

回答

1

我有同樣的問題,因爲我不是太熟悉ContactA和ContactB是如何工作的,我給了每個對象的名稱和檢查,如果這兩個物體發生碰撞,像這樣。

func didMoveToView(view: SKView) { 

     objectA = self.childNodeWithName("ObjectA") as! SKSpriteNode! 
     objectB = self.childNodeWithName("ObjectB") as! SKSpriteNode! 
} 

func didBeginContact(contact: SKPhysicsContact) { 

     let contactA: SKPhysicsBody = contact.bodyA 
     let contactB: SKPhysicsBody = contact.bodyB 

     let nodeA = contactA.node as! SKSpriteNode 
     let nodeB = contactB.node as! SKSpriteNode 

     if nodeA.name == "ObjectA" && nodeB.name == "ObjectB" { 

       //do something 
     } 

    } 
+0

ContactA和ContactB只是兩個相互接觸的物體,它們的順序無法確定。通過字符串檢查比較比檢查類別比較慢,所以我建議避免它,如果可以的話 – Knight0fDragon

0

檢測碰撞屬性是接觸式測試位掩碼,這就是爲什麼它只是通過我認爲你有碰撞位掩碼和接觸式測試位掩碼相互混淆

接觸測試是什麼檢測接觸同時碰撞位掩碼允許機構通過彼此

1

閱讀我對此問題的回答SpriteKit - Making certain SpriteNodes NOT collide without disabling their physics bodies它描述了碰撞和聯繫人之間的區別。

也嘗試實現我的checkPhysics()函數(源代碼在同一個答案中),它將分析您的場景並列出哪些節點與其他節點發生衝突,以及哪些節點在聯繫其他節點時通知它們。

的輸出將是這樣一個physicsDemo我有4個SKSPriteNodes稱爲shape_blueSquare,shape_redCircle,shape_purpleSquare,shape_greenRect & shape_yellowTriangle和所謂的「Screen_edge」屏幕周圍的邊框。 「

Optional("shape_blueSquare") collides with Optional("Screen_edge") 
Optional("shape_blueSquare") collides with Optional("shape_redCircle") 
Optional("shape_blueSquare") collides with Optional("shape_purpleSquare") 
Optional("shape_blueSquare") collides with Optional("shape_greenRect") 
Optional("shape_redCircle") collides with Optional("Screen_edge") 
Optional("shape_redCircle") collides with Optional("shape_blueSquare") 
Optional("shape_redCircle") notifies when contacting Optional("shape_purpleSquare") 
Optional("shape_redCircle") collides with Optional("shape_greenRect") 
Optional("shape_redCircle") notifies when contacting Optional("shape_greenRect") 
Optional("shape_purpleSquare") collides with Optional("Screen_edge") 
Optional("shape_purpleSquare") collides with Optional("shape_greenRect") 
Category for Optional("shape_greenRect") does not appear to be set correctly as 4294967295 
ptional("shape_greenRect") collides with Optional("Screen_edge") 
Optional("shape_yellowTriangle") collides with Optional("Screen_edge") 
Optional("shape_yellowTriangle") notifies when contacting Optional("shape_redCircle") 
Optional("shape_yellowTriangle") collides with Optional("shape_greenRect") 
Optional("shape_yellowTriangle") notifies when contacting Optional("shape_greenRect")