iOS Swift中didBeginContact未被调用

8
我过去两天一直在努力使两个SKSpriteNodes注册碰撞并调用didBegin#contact方法。
我已经为两个对象设置了categoryBitMask、contactTestBitMask和collisionTestBitMask属性。
我还将它们的dynamic属性都设置为true。
看起来initPhysics()方法已经正确设置了physicsWorld。
我的期望是调用didBegin#Contact方法,但实际上没有调用。
//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
在这个平台上,不欢迎代码转储。 - Mundi
请注意,除了collisionBitMask之外,您还必须设置contactTestBitMask。这是通常的陷阱。请注意,在storyboard编辑器中,默认情况下将contactTestBitMask保留为零 - 这是通常的问题。只需将其设置为“1”即可。 - Fattie
4个回答

11

'didBeginContact'已在Swift 3中更改为'didBegin'

func didBegin(_ contact: SKPhysicsContact) { //操作 }

我有一个来自Swift 2的代码,并且'didBeginContact'存在于其中,但没有被调用。 经过一段时间的研究,我发现该函数进行了更改。 因此,我认为我的答案可能会对某些人有所帮助。


3

如果你想在汽车和慢速汽车之间建立联系,你需要初始化两个物理体的categoryBitMask(我认为你已经做过)。查看下面的代码以获取两个物理体之间的接触。当有接触时,它会返回你的display函数:

//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)

谢谢,不幸的是didBeginContact()根本没有被调用。我已经将整个代码剥离,只是将精灵放在屏幕上,设置物理引擎,然后运行一个动作使其中一个碰到另一个,但不幸的是它仍然无法工作。 - Headstock67
你设置了 carslowCarcategoryBitMask 吗?在你的代码中,你设置了 carBodyslowCarBody - Haox
2
嗨Haox,问题的原因在于我设置了精灵节点的physicsBody框架方式,见我的回答。虽然非常感谢你的帮助,因为它给了我在下一个编码挑战阶段一些有价值的见解。再次感谢! - Headstock67
很高兴能为你提供帮助 :D - Haox

2
事实证明,问题很简单。在我的原始代码中,我设置了SKPhysicsBody检测框架的参数,如下所示: let carBody = SKPhysicsBody( rectangleOfSize: car.frame.size, center: car.position) 同样,我也为我要测试物理碰撞的第二个节点做了同样的事情。
只需删除'center:'参数,如下所示: let carBody = SKPhysicsBody(rectangleOfSize: car.frame.size) 对于这两个精灵节点,问题得到了解决,节点现在相互碰撞并按预期推开自己。

1
请注意,两个静态物体之间不会检测到接触。
(node.physicsBody?.isDynamic = false)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接