SpriteKit - 联系错误

时间:2015-12-26 19:16:47

标签: ios swift sprite-kit

My Hero / Player实例可以通过触摸敌人实例或enemyBullet实例来销毁。这是我的敌人:

physicsBody = SKPhysicsBody(rectangleOfSize: size)
physicsBody?.categoryBitMask = PhysicsCategory.enemy
physicsBody?.collisionBitMask = 0
physicsBody?.contactTestBitMask = PhysicsCategory.bullet
physicsBody?.affectedByGravity = false
physicsBody?.allowsRotation = false
physicsBody?.dynamic = true

这是我的敌人Bullet:

bullet.physicsBody = SKPhysicsBody(rectangleOfSize: bullet.size)
bullet.physicsBody?.categoryBitMask = PhysicsCategory.enemyBullet
bullet.physicsBody?.contactTestBitMask = PhysicsCategory.hero
bullet.physicsBody?.affectedByGravity = false
bullet.physicsBody?.dynamic = false

这是我的英雄:

physicsBody = SKPhysicsBody(rectangleOfSize: size)
physicsBody?.affectedByGravity = false
physicsBody?.categoryBitMask = PhysicsCategory.hero
physicsBody?.contactTestBitMask = PhysicsCategory.enemy | PhysicsCategory.enemyBullet
physicsBody?.dynamic = false

我的玩家与敌人的实例正确接触,但没有与敌人小贩接触。相反,当一个敌人射击时,会有一个随机的SKPhysicsContact实例化。这就是我的处理功能:

func didBeginContact(contact: SKPhysicsContact) {
        // Enemy + bullet
        if((contact.bodyA.categoryBitMask == PhysicsCategory.enemy && contact.bodyB.categoryBitMask == PhysicsCategory.bullet) || (contact.bodyA.categoryBitMask == PhysicsCategory.bullet && contact.bodyB.categoryBitMask == PhysicsCategory.enemy)) {
            // TODO
        }

        // Hero + enemy
        else if((contact.bodyA.categoryBitMask == PhysicsCategory.hero && contact.bodyB.categoryBitMask == PhysicsCategory.enemy) || (contact.bodyA.categoryBitMask == PhysicsCategory.enemy && contact.bodyB.categoryBitMask == PhysicsCategory.hero)) {
            print("HERO AND ENEMY")
        }

        // Hero + enemyBullet
        else if((contact.bodyA.categoryBitMask == PhysicsCategory.hero && contact.bodyB.categoryBitMask == PhysicsCategory.enemyBullet) || (contact.bodyA.categoryBitMask == PhysicsCategory.enemyBullet && contact.bodyB.categoryBitMask == PhysicsCategory.hero)) {
            print("HERO AND BULLET")
        }
        else {
            print("DEBUG: \(contact.bodyA.categoryBitMask) AND ˜\(contact.bodyB.categoryBitMask)")
        }
    }

所以:所发生的事情是,每当敌人射击(射击敌人)时,它将在我的处理功能中运行到其他地方。这将打印" DEBUG:1和6"。 1 =敌人,6 =敌人。

为什么我的敌人在射击子弹时会抛出一个接触?当英雄被敌人击中时,我如何能够检测到我的游戏?

编辑:感谢@KnightOfDragon:

  1. 使用ContactBitMask和CategoryBitMask时,请确保不要简单地将它们设置为1,2,3,4等。将它们设置为:

    static let environment:UInt32 = 0b00000000000000000000000000000001 static let powerup:UInt32 = 0b00000000000000000000000000000010 static let hero:UInt32 = 0b00000000000000000000000000100000 static let bullet:UInt32 = 0b00000000000000000000000001000000 static let enemy:UInt32 = 0b00000000000000000100000000000000 static let enemyBullet:UInt32 = 0b00000000000000001000000000000000

    static let enemyAndEnemyBullet:UInt32 = 0b00000000000000001100000000000000

  2. 为了对上帝的爱:当你想要使用来自又名SKPhysicsContact的联系人的精灵时,总是将它们设置为dynamic = true。否则它就无法工作。

1 个答案:

答案 0 :(得分:2)

如果您使用6,那么您没有正确使用面具。掩码值必须以2的幂表示,因此没有比特彼此重叠。通过说6,你说0110,所以你的敌人的子弹可以联系任何2和4代表。发布您的类别枚举,以便我可以完成此答案。

修改

static let enemy: UInt32       = 0b00000000000000000000000000000001 
static let bullet: UInt32      = 0b00000000000000000000000000000010 
static let hero: UInt32        = 0b00000000000000000000000000000100 
static let environment: UInt32 = 0b00000000000000000000000000001000 
static let powerup: UInt32     = 0b00000000000000000000000000010000
static let enemyBullet: UInt32 = 0b00000000000000000000000000100000

然后,为了使您的代码更具可读性,您可以执行

之类的操作
static let enemyAndEnemyBullet: UInt32 = 0b00000000000000000000000000100001
...
player.contactBitMask =  enemyAndEnemyBullet;
...

if((bodyA == player.categoryBitMask) && (bodyB.categoryBitMask | enemyAndEnemyBullet) > 0)
{
    ...
}

而不是使用

player.contactBitMask =  enemy | enemyBullet;
...
if((bodyA == player.categoryBitMask) && (bodyB.categoryBitMask == enemy || bodyB == enemyBullet))
{
    ...
}

现在不需要所有前导零,我这样做了,这样你就可以看到面具是如何工作的以及最大值是多少。 (32种不同的面具)