【问题标题】:SpriteKit - Wrong contactSpriteKit - 错误的联系方式
【发布时间】:2016-04-01 04:12:09
【问题描述】:

我的 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.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)")
        }
    }

所以:发生的情况是,每当敌人射击(射击enemyBullet)时,它都会在我的处理函数中运行到 else 。这将打印“调试:1 和 6”。 1 = 敌人,6 = 敌人子弹。

为什么我的敌人在发射子弹时要进行接触?如何让我的游戏检测到英雄何时被敌人子弹击中?

编辑:感谢@KnightOfDragon:

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

    静态让环境:UInt32 = 0b000000000000000000000000000000001 静态让上电:UInt32 = 0b00000000000000000000000000000010 静态让英雄:UInt32 = 0b00000000000000000000000000100000 静态让子弹:UInt32 = 0b00000000000000000000000001000000 静态让敌人:UInt32 = 0b00000000000000000100000000000000 静态让敌人子弹:UInt32 = 0b00000000000000001000000000000000

    静态让enemyAndEnemyBullet: UInt32 = 0b00000000000000001100000000000000

  2. 看在上帝的份上:在使用精灵时,您希望与 SKPhysicsContact 联系,请始终将它们设置为 dynamic = true。否则将无法正常工作。

【问题讨论】:

    标签: ios swift sprite-kit


    【解决方案1】:

    如果您使用的是 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 种不同的面具)

    【讨论】:

    • 静态让敌人:UInt32 = 1 静态让子弹:UInt32 = 2 静态让英雄:UInt32 = 3 静态让环境:UInt32 = 4 静态让上电:UInt32 = 5 静态让敌人子弹:UInt32 = 6不知道那个。所以我应该做1,2,4,8,16?
    • @KnightOfDragon:非常感谢您的回答。我将我的代码调整为不使用 1、2、3、4 等。我的枚举了。我仍然没有联系到英雄 + 敌人子弹。这一次,根本没有抛出 SKPhysicsContact。 (除了枚举之外,我没有编辑任何其他内容!)
    • 你可能要发更多了,你是说根本没有联系,还是说没有联系到英雄和子弹的范围内
    • 另外,你把我甩了,你说的是枚举,但让我发布常量......这是什么?
    • @KnightOfDragon:对不起,我用错了名字。这是属于我的问题的完整代码:pastebin.com/Tfs1SZbS。任何帮助表示赞赏。
    猜你喜欢
    • 2015-08-31
    • 1970-01-01
    • 1970-01-01
    • 2017-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-16
    • 1970-01-01
    相关资源
    最近更新 更多