Swift:两个节点之间的接触检测?

时间:2015-04-08 23:26:18

标签: swift sprite-kit skphysicsbody

好吧,所以我一直在关注各种其他SO链接并尝试解决这个问题 - 我需要在两个节点之间进行接触检测。不是碰撞检测,我学会了在节点周围相互反弹的结果。我不想让他们互相敲打,我只是想知道他们何时碰到。

现在我有2个节点的物理实体,saviorchicken1以及ground所在的地面(savior)。这些都在这里设置:

        savior.physicsBody?.dynamic = true
        savior.physicsBody?.allowsRotation = false
        savior.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(savior.size.width, savior.size.height))

        chicken1.physicsBody?.dynamic = true
        chicken1.physicsBody?.allowsRotation = false
        chicken1.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(chicken1.size.width, chicken1.size.height)) 

        ground.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(self.frame.size.width, groundTexture.size().height*2))
        ground.physicsBody?.dynamic = false

我需要在saviorchicken1之间设置联系人检测。似乎有各种方法可以做到这一点,但这就是我所说的:

//Contact detection

        self.physicsWorld.contactDelegate = self

        savior.physicsBody?.categoryBitMask = saviorCategory
        savior.physicsBody?.contactTestBitMask = animalCategory
        savior.physicsBody?.collisionBitMask = 0

        chicken1.physicsBody?.categoryBitMask = animalCategory
        chicken1.physicsBody?.contactTestBitMask = saviorCategory
        chicken1.physicsBody?.collisionBitMask = 0

        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 == 0 && secondBody.categoryBitMask == 1 {
                println("they made contact")
            }

    }

此代码导致savior直接ground直到chicken1,没有接触检测,因为即使saviorchicken1触摸,没有任何反应。

我需要saviorground继续发生碰撞,但我不想让saviorchicken1发生碰撞,只需触摸即可。 程序需要在触摸时执行某些操作。 这是一团糟,但我该如何解决这个问题?

编辑:

以下是我的内容,animalCategory为了清晰起见已更改为chickenCategory,未检测到任何联系。 savior ground仍属 self.physicsWorld.contactDelegate = self var screenTouches = Bool() let saviorCategory: UInt32 = 0x1 << 0 let chickenCategory: UInt32 = 0x1 << 1 savior.physicsBody?.categoryBitMask = saviorCategory savior.physicsBody?.contactTestBitMask = chickenCategory savior.physicsBody?.collisionBitMask = chickenCategory chicken1.physicsBody?.categoryBitMask = chickenCategory chicken1.physicsBody?.contactTestBitMask = saviorCategory chicken1.physicsBody?.collisionBitMask = saviorCategory func didBeginContact(contact: SKPhysicsContact) { var firstBody : SKPhysicsBody var secondBody : SKPhysicsBody if contact.bodyA.categoryBitMask == chickenCategory && contact.bodyB.categoryBitMask == saviorCategory { println("contact made") savior.hidden = true } else if contact.bodyA.categoryBitMask == saviorCategory && contact.bodyB.categoryBitMask == chickenCategory { println("contact made") savior.hidden = true } }

{{1}}

3 个答案:

答案 0 :(得分:0)

好的,所以你想要的只是检测他们触摸过,但你不希望他们互相推动。我会在didBeginContact中将你的碰撞检测放在它们之间,制作它们的physicsbody = nil,这样当它们发生碰撞时就知道它们会发生碰撞,当你把它碰撞时它会让它们相互通过。如果你想让代码做其他事情,那就在你将物理实体设为零之前放置代码。此外,如果你想放回他们的物理学家,就把它放回去。

答案 1 :(得分:0)

对于仍然坚持这一点的任何人,如果你想检测到两个精灵彼此接触而没有他们实际上彼此有物理效应(即引起运动),那么关键是将collisionBitMask的{​​{1}}属性设置为0:

physicsBody

这意味着您将收到node.physicsBody!.collisionBitMask = 0 中的事件,但相互作用的对象不会对彼此产生实际的物理效果。

答案 2 :(得分:-1)

这是怎么做的:

  1. 设置类别位掩码:

    let saviorCategory: UInt32 = 0x1 << 0
    let chickenCategory: UInt32 = 0x1 << 1
    let groundCategory: UInt32 = 0x1 << 2
    
  2. 设置物理机构:

    func didMove(to: View) {
    
        savior.physicsBody?.categoryBitMask = saviorCategory
        savior.physicsBody?.contactTestBitMask = chickenCategory
        savior.physicsBody?.collisionBitMask = groundCategory
    
        chicken1.physicsBody?.categoryBitMask = animalCategory
        chicken1.physicsBody?.contactTestBitMask = saviorCategory
        chicken1.physicsBody?.collisionBitMask = groundCategory
    
        ground.physicsBody?.categoryBitMask = groundCategory
        ground.physicsBody?.contactTestBitMask = 0 // No contact detection for ground
        ground.physicsBody?.collisionBitMask = UInt32.Max // Everything collides with the ground
    
        physicsWorld.contactDelegate = self
    
        // Rest of didMoveToView
    }
    
  3. 注意:实际上没有必要将鸡定义为接触救世主和救世主,就像接触鸡一样;你只需要定义一个与另一个联系,但它可以使代码更具可读性,并说每个代码都与另一个联系。

    1. 实施didBegin:

      func didBeginContact(contact: SKPhysicsContact) {
          let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
          switch contactMask {
      
          case chickenCategory | saviourCategory:
              print("Collision between chicken and saviour")
              let saviour = contact.bodyA.categoryBitMask == saviourCategory ? contact.bodyA.node! : contact.bodyB.node!
              saviour.hidden = true
      
          default :
              //Some other contact has occurred
              print("Some other contact")
          }
      }
      
    2. 不要忘记将您的课程设为SKPhysicsContactDelegate

    3. 查看以下示例:

    4. Attack button in SpriteKit