为什么没有碰撞时我的碰撞被记录了?

时间:2014-08-15 16:02:35

标签: ios swift sprite-kit xcode6 skphysicsbody

请耐心等待,我已经和XCode / IOS合作了一天,所以你可能需要解释一下......

我有一个碰撞方法:

func didBeginContact(contact: SKPhysicsContact!) {

    if (contact != nil && contact.bodyA != nil && contact.bodyB != nil)
    {
        var firstBody:SKPhysicsBody
        var seconBody:SKPhysicsBody

        if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask)
        {
            firstBody = contact.bodyA
            seconBody = contact.bodyB
        }
        else
        {
            firstBody = contact.bodyB
            seconBody = contact.bodyA
        }

        if (firstBody.categoryBitMask & torpedoCategory != 0 && seconBody.categoryBitMask & alienCategory != 0)
        {

            if firstBody.node != nil && seconBody.node != nil {
                torpedodidCollideWithAlien(firstBody.node as SKSpriteNode, alien: seconBody.node as SKSpriteNode)

            }
        }
    }
}

由此触发:

    var alien:SKSpriteNode = SKSpriteNode(imageNamed: "Alien")

    alien.physicsBody = SKPhysicsBody(texture: alien.texture, size: alien.size)
    alien.physicsBody.categoryBitMask = alienCategory
    alien.physicsBody.contactTestBitMask = torpedoCategory
    alien.physicsBody.collisionBitMask = 0
    alien.zPosition = -100000

我正在尝试使用XCode 6中可用的像素冲突。问题是didBeginContact方法在没有冲突时被触发,并且在一次冲突时会多次触发。

我是否错误地使用了物理系统?

以下是整个项目的链接:https://www.dropbox.com/s/1npctvb99vw2l7x/BubbleBurst.zip

面具的值:

    let alienCategory:UInt32 = 0x1 << 1    
    let torpedoCategory:UInt32 = 0x1 << 0

2 个答案:

答案 0 :(得分:0)

我知道这不是你真正的答案,但它可能会帮助你找到真正的答案。

I'm trying to use the pixel collision available in XCode 6. The issue is that the didBeginContact method is triggered when there is no collision, and it is triggered multiple times for one collision.

碰撞和接触是不同的事情。使用contactTestBitMask来检测联系人(您正在做的事情)和collisionBitMask以启用与这些联系人相关的物理(碰撞本身)。在更实际的术语中,contactTestBitMask应该用于使用您的代码处理某些内容,并且SpriteKit使用collisionBitMask来使对象在碰到另一个对象时反弹。

如果你使用collisionBitMask,你可能会摆脱你的第二个问题(&#34; [didBeginContact]在一次碰撞中多次触发&#34;)。

对于您的第一个问题(&#34;在没有碰撞时触发了didBeginContact [...]&#34;),我尝试更改您的alien.physicsBody。我会完全猜到这一部分,但也许你的图像就像300x300,你希望你的外星人的像素大小为150x150。也许你的alien.physicsBody比它看起来更大,因此它的物理体在视觉表现相同之前触及另一个物体的身体。

答案 1 :(得分:0)

在您设置SKView的viewController中,我建议您在进行整理时将其打开。

skView.showsPhysics = true

对于多次发生的接触,这是完全正常的。如果您告诉SpriteKit测试接触重叠的两个节点,它将读取为每次循环运行的接触(didSimulatePhysics)。假设您想要一个鱼雷来摧毁一个外星人,需要将其中一个或两个从场景中移除以阻止再次被读取(可选地隐藏或移动)。或者,例如,如果你想让它携带多个鱼雷来摧毁外星人,鱼雷需要在接触时被移除/移动。

正如布鲁诺所提到的,SpriteKit中的碰撞意味着两个物体可以作为固体,相互进入。玩家可能会与墙壁碰撞(无法通过它),但玩家可能会通过怪物。

你的didBeginContact代码也可以简单得多。这是一个测试玩家是否已经击中其他三个物理主体contactBitMasks之一的示例。

func didBeginContact(contact: SKPhysicsContact) {
    var other:SKPhysicsBody = contact.bodyA.categoryBitMask == Contact.Player ? contact.bodyB : contact.bodyA

    if other.categoryBitMask == Contact.Scene {
        // Do stuff for player hitting scene edge
    } else if other.categoryBitMask == Contact.Object {
        // Do stuff for player hitting the hazards
    } else if other.categoryBitMask == Contact.Score {
       // Do stuff for player scoring points
    }
}