8

I have been struggling for the past two days to get two SKSpriteNodes to register a collision and evoke didBegin#contact.

I've set their bit masks 'categoryBitMask', 'contactTestBitMask' and 'collisionTestBitMask' for both objects.

I've also set the 'dynamic' property for both to 'true'

initPhysics() seems to set up the physicsWorld okay.

All I'm expecting is that didBegin#Contact is called, but it is not

//Set up Physicsbody bit masks
let playerCarBitMask: UInt32 = 0x1 << 1
let slowCarBitMask: UInt32 = 0x1 << 2



//initPhysics
func initPhysics() {
    println("(((((((((((((( Initiating Physicsbody ))))))))))))))")
    self.physicsWorld.contactDelegate = self
    self.physicsWorld.gravity = CGVector.zeroVector

    println("self.physicsWorld.contactDelegate = \(self.physicsWorld.contactDelegate)")

}

//setupPlayer
func setupPlayer() {

    car = SKSpriteNode(imageNamed: "redCarUp")
    car.setScale(2.0)
    car.position = CGPoint(x: 800, y: 400)
    car.zPosition = 100
    car.name = "car"

    gameNode.addChild(car)

    let carBody = SKPhysicsBody(
        rectangleOfSize: car.frame.size, center: car.position)

    carBody.dynamic = true
    carBody.categoryBitMask = playerCarBitMask
    carBody.contactTestBitMask = slowCarBitMask
    carBody.mass = 5
    carBody.collisionBitMask = slowCarBitMask
    car.physicsBody = carBody

    println("carBody = \(carBody)")
    println("carBody.dynamic = \(carBody.dynamic)")
    println("carBody.mass = \(carBody.mass)")
    println("carBody.categoryBitMask = \(carBody.categoryBitMask)")
    println("carBody.contactTestBitMask = \(carBody.contactTestBitMask)")
    println("carBody.collisionBitMask = \(carBody.contactTestBitMask)")



    slowCar = SKSpriteNode(imageNamed: "blueCarUp")
    slowCar.setScale(2.0)
    let slowCarScenePos = CGPoint(
        x: 680,
        y: 2048)


    slowCar.position = gameNode.convertPoint(slowCarScenePos, fromNode: self)
    println("slowCar.position = \(slowCar.position) ****")
    slowCar.zPosition = 80
    slowCar.name = "slowCar"



    let slowCarBody = SKPhysicsBody(
        rectangleOfSize: slowCar.frame.size, center: slowCar.position)


    println("slowCar = \(slowCar) ****")

    slowCarBody.dynamic = true
    slowCarBody.categoryBitMask = slowCarBitMask
    slowCarBody.contactTestBitMask = playerCarBitMask
    slowCarBody.mass = 5
    slowCarBody.collisionBitMask = playerCarBitMask
    slowCar.physicsBody = slowCarBody
    gameNode.addChild(slowCar)



}

func didBeginContact(contact: SKPhysicsContact!) {
    println("*******************PhysicsContact********************")
}
Fattie
  • 27,874
  • 70
  • 431
  • 719
Headstock67
  • 151
  • 2
  • 8
  • 1
    Code dumps are not appreciated on this platform. – Mundi Oct 18 '14 at 10:37
  • note that **as well as collisionBitMask, you must set contactTestBitMask**. this is the usual gotchya. note that **in the storyboard editor, it leaves contactTestBitMask as zero by default** - it's the usual problem. just set it to "1" – Fattie Oct 23 '17 at 21:35

4 Answers4

11

'didBeginContact' has been changed to 'didBegin' in swift 3

func didBegin(_ contact: SKPhysicsContact) { //stuff }

I had a code from swift 2 and 'didBeginContact' was sitting there but wasn't being called. After quite a white I figured out that the function was changed. So, I thought my answer could help someone.

Akhilendra Singh
  • 661
  • 11
  • 16
3

If you want make a contact between car and slowCar you have to init the categoryBitMask of both physicsBodies (I think you did). See the code below to get contact between two physicsBodies. When there is a contact it returns your display function :

//init your categoryBitMask : 
let carCategory:UInt32 = 0x1 << 0
let SlowCarCategory:UInt32 = 0x1 << 1


//init car
car.physicsBody?.categoryBitMask = carCategory
car.physicsBody?.contactTestBitMask = slowCarCategory

//init slowCar 
slowCar.physicsBody?.categoryBitMask = slowCarCategory
slowCar.physicsBody?.contactTestBitMask = CarCategory

// set your contact function
func didBeginContact(contact: SKPhysicsContact!)
{
    var firstBody: SKPhysicsBody
    var secondBody: SKPhysicsBody


    if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask)
    {
        firstBody = contact.bodyA
        secondBody = contact.bodyB

    }
    else
    {
        firstBody = contact.bodyB
        secondBody = contact.bodyA
    }


    if ((firstBody.categoryBitMask & carCategory) != 0 && (secondBody.categoryBitMask & slowCarCategory) != 0)
    {
        displayfunction(firstBody.node as SKSpriteNode, car: secondBody.node as SKSpriteNode)
    }
}

func displayFunction (slowCar : SKSpriteNode, car : SKSpriteNode)
Haox
  • 608
  • 1
  • 7
  • 23
  • Thanks, unfortunately didBeginContact() is not being evoked in the first place. I have just stripped the whole code back so that it just puts the sprites on the screen, sets up the physics engine and then runs an action to make one hit the other but unfortunately it is still not working. – Headstock67 Oct 19 '14 at 08:31
  • Do you set the categoryBitMask of `car`and `slowCar`? In your code you set `carBody` and `slowCarBody` – Haox Oct 19 '14 at 08:58
  • 2
    Hey Haox, it turned out that the problem was due to the manner in which I was setting up the physicsBody frame for the sprite node, see my answer. Your help was appreciated though because its given me some valuable insight into the next stage of my coding challenge. Thanks again! – Headstock67 Oct 19 '14 at 09:08
  • Glad to help you for later :D – Haox Oct 19 '14 at 09:11
2

It turned out to be a simple problem. In my original code I was setting parameters for the SKPhysicsBody detection frame like so:

let carBody = SKPhysicsBody( rectangleOfSize: car.frame.size, center: car.position)

Similarly I was doing the same for the second node that I was testing physics collisions for.

Simply removing the 'centre:' parameters like so:

let carBody = SKPhysicsBody(rectangleOfSize: car.frame.size)

for the two sprite nodes solved the problem and the nodes now crash into each other and push themselves aside as expected.

Headstock67
  • 151
  • 2
  • 8
1

Please Note that contact will not be detected between two static bodies

(node.physicsBody?.isDynamic = false)
Petter Friberg
  • 21,252
  • 9
  • 60
  • 109
Binoy jose
  • 461
  • 4
  • 9