SKPhysicsContact 没有用子弹接触敌人

Posted

技术标签:

【中文标题】SKPhysicsContact 没有用子弹接触敌人【英文标题】:SKPhysicsContact not contacting enemy with bullet 【发布时间】:2021-11-30 16:29:31 【问题描述】:

我希望我的 categorybitmasks 设置正确,但我下面的代码应该让我的子弹和敌人接触,然后相互删除。什么都没有发生,它们只是碰撞并仍然停留在屏幕上

func didBeginContact(联系人: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 & bulletCategory) != 0 &&
    (secondBody.categoryBitMask & enemyCategory) != 0 
        destroyEnemy(bullet: firstBody.node as! SKSpriteNode, enemy: secondBody.node as! SKSpriteNode)
  


func destroyEnemy(bullet: SKSpriteNode, enemy: SKSpriteNode) 
  
  bullet.removeFromParent()
  enemy.removeFromParent()

    enemy.physicsBody?.categoryBitMask = CollisionTypes.enemy.rawValue
    enemy.physicsBody?.contactTestBitMask = CollisionTypes.bullet.rawValue
    enemy.physicsBody?.collisionBitMask = CollisionTypes.bullet.rawValue

bullet.physicsBody?.categoryBitMask = CollisionTypes.bullet.rawValue bullet.physicsBody?.contactTestBitMask = CollisionTypes.enemy.rawValue bullet.physicsBody?.collisionBitMask = CollisionTypes.enemy.rawValue

【问题讨论】:

“我已经正确设置了我的 categorybitmasks”谁知道呢? 你有接到电话吗?您是否忘记设置联系人代表? 将 print("didBegin:entered") 作为didBegin(contact:) 的第一行,以便您知道是否有任何联系人正在注册。您是否已完成接触检测所需的所有其他工作? ***.com/a/51041474/1430420 已设置联系人代表。打印后没有任何内容被回调。他们之间肯定有冲突,只是接触后没有注册。 您可以确定的一件事是,如果没有调用 didBegin,那么您没有正确设置联系人 - 它永远不会“不起作用”。跨度> 【参考方案1】:

这本身不是一个答案,但评论有点长:

在你的didBegin 你有:

if (firstBody.categoryBitMask & bulletCategory) != 0 &&
    (secondBody.categoryBitMask & enemyCategory) != 0 
        destroyEnemy(bullet: firstBody.node as! SKSpriteNode, enemy: secondBody.node as! SKSpriteNode)

如果 firstBody 是敌人而 secondBody 是子弹会发生什么?似乎发生联系时要运行的代码不会触发。如果没有看到您的 categoryBitMask 定义,我们将不会知道,因为您似乎是按 categoryBitMask 值的升序分配第一个和第二个正文。

您可以确认这是否与 if 块内的另一个 print 一起使用。

我从来没有真正喜欢过didBegin 的这种形式,而且我个人觉得这种风格更具可读性:

  func didBegin(_ contact: SKPhysicsContact) 
     print("didBeginContact entered for \(String(describing: contact.bodyA.node!.name)) and \(String(describing: contact.bodyB.node!.name))")

     let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask

     switch contactMask 
     case bulletCategory | enemyCategory:
        print("bullet and enemy have contacted.")
        let bulletNode = contact.bodyA.categoryBitMask == bulletCategory ? contact.bodyA.node : contact.bodyB.node
        let enemyNode = contact.bodyA.categoryBitMask == enemyCategory ? contact.bodyA.node : contact.bodyB.node
        destroyEnemy(bullet: bulletNode, enemy: enemyNode)
     case playerCategory | enemyCategory:
        // Handle player/Enemy collisions
     default:
        print("Some other contact occurred")
     

【讨论】:

以上是关于SKPhysicsContact 没有用子弹接触敌人的主要内容,如果未能解决你的问题,请参考以下文章

子弹物理:接触力/冲量

多次检测到碰撞

三精灵节点碰撞

少儿编程Scratch第四讲:射击游戏的制作,克隆的奥秘

python--飞机大战

CS高手指点 一般高手都在控制平台中 都打那些优化呀 为啥他调完感觉子弹没以前爱飘了 舒服多了