iOS Swift didBeginContact not being called

早过忘川 提交于 2019-12-05 22:09:06

问题


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********************")
}

回答1:


'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.




回答2:


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)



回答3:


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.




回答4:


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

(node.physicsBody?.isDynamic = false)


来源:https://stackoverflow.com/questions/26438108/ios-swift-didbegincontact-not-being-called

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!