所有碰撞都在工作,除了一个。我该怎么办?

时间:2016-01-05 19:23:59

标签: swift sprite-kit collision-detection

我的场景中间有一个由四种不同颜色组成的正方形。同时,我从场景的每一侧随机生成相同颜色的较小正方形,意图与中间的正方形相撞。 (蓝色到蓝色,黄色到黄色等)。

话虽如此,我的四次碰撞中有三次正常工作。红色击中红色,蓝色击中蓝色细,黄色击中黄色,但我的绿色方块不想做它应该做的事情。这就是我设置碰撞的方法:

  struct PhysicsCatagory {
     static let FirstPerson : UInt32 = 0x1 << 1
     static let SecondPerson : UInt32 = 0x1 << 2
     static let ThirdPerson : UInt32 = 0x1 << 4
     static let FourthPerson : UInt32 = 0x1 << 8
  }

  smallBlue.physicsBody?.categoryBitMask = PhysicsCatagory.FirstPerson
  smallBlue.physicsBody?.contactTestBitMask = PhysicsCatagory.SecondPerson

  smallRed.physicsBody?.categoryBitMask = PhysicsCatagory.ThirdPerson
  smallRed.physicsBody?.contactTestBitMask = PhysicsCatagory.FourthPerson
  smallRed.physicsBody?.collisionBitMask = 0

  smallGreen.physicsBody?.categoryBitMask = PhysicsCatagory.ThirdPerson
  smallGreen.physicsBody?.contactTestBitMask = PhysicsCatagory.FourthPerson
  smallGreen.physicsBody?.collisionBitMask = 0

  bigRed.physicsBody?.contactTestBitMask = PhysicsCatagory.FourthPerson
  bigRed.physicsBody?.categoryBitMask = PhysicsCatagory.ThirdPerson
  bigRed.physicsBody?.collisionBitMask = 0

  bigGreen.physicsBody?.categoryBitMask = PhysicsCatagory.ThirdPerson
  bigGreen.physicsBody?.contactTestBitMask = PhysicsCatagory.FourthPerson
  bigGreen.physicsBody?.collisionBitMask = 0

  bigBlue.physicsBody?.categoryBitMask = PhysicsCatagory.FirstPerson
  bigBlue.physicsBody?.contactTestBitMask = PhysicsCatagory.SecondPerson
  bigBlue.physicsBody?.collisionBitMask = 0

  bigYellow.physicsBody?.categoryBitMask = PhysicsCatagory.FirstPerson
  bigYellow.physicsBody?.collisionBitMask = 0
  bigYellow.physicsBody?.contactTestBitMask = PhysicsCatagory.SecondPerson

  func didBeginContact() {
      let firstBody = contact.bodyA.node as! SKSpriteNode // registering as big blue square
      let secondBody = contact.bodyB.node as! SKSpriteNode // register ing as little blue square

      if firstBody.color == secondBody.color { //if the colors collide, remove small one from the scene
        //firstBody.removeFromParent()
          label.text = "\(numPoints)" // points label increment
          numPoints++ //points label increment 
          secondBody.removeFromParent()
      }

      if firstBody.color != secondBody.color { // if colors don't match, call gameOver scene
        //gameOver()
      }

      let thirdBody = contact.bodyA.node as! SKSpriteNode
      let fourthBody = contact.bodyB.node as! SKSpriteNode

      if thirdBody.color ==  fourthBody.color {           
        label.text = "\(numPoints)"
        numPoints++
        fourthBody.removeFromParent()
      }

      if thirdBody.color != fourthBody.color {
        //gameOver()
      }

      let fifthBody = contact.bodyA.node as! SKSpriteNode
      let sixthBody = contact.bodyB.node as! SKSpriteNode

      if fifthBody.color ==  sixthBody.color {            
        label.text = "\(numPoints)"
        numPoints++
        secondBody.removeFromParent()
      }

      let seventhBody = contact.bodyA.node as! SKSpriteNode
      let eighthBody = contact.bodyB.node as! SKSpriteNode

      if seventhBody.color == eighthBody.color {
          label.text = "\(numPoints)"
          numPoints++
          eighthBody.removeFromParent()
          print("green removed")
      }        
  }

有什么我想念的吗?如有必要,会发布更多代码。

以下是我正在寻找的英语表示

if small red equals big red then gain a point, update the label, and remove small red

if small blue equals big blue then gain a point, update the labelm and remove small blue

if small yellow equals big yellow then gain a point, update points label and remove little yellow.

if small green equals big green, gain point and update label and remove little yellow from scene

if little blue does not equal big blue, call game over scene

if little yellow does not equal big yellow, call game over scene

if little red does not equal big red, call game over scene

if little green does not equal big green, call game over scene

1 个答案:

答案 0 :(得分:1)

接触体是如何工作的,每次2个节点碰撞时都会调用didBeginContact,也就是说,在1个更新周期中,如果红色点亮蓝色,红色点亮绿色,则会发生2次调用didBeginContact。这意味着你创建第三个Body并且第四个没有意义,因为它每次最终都与firstBody相同。这意味着我们可以完全删除所有代码,并按照以下方式删除:

func didBeginContact() {
    let firstBody = contact.bodyA.node as! SKSpriteNode // registering as big blue square
    let secondBody = contact.bodyB.node as! SKSpriteNode // register ing as little blue square

    if firstBody.color == secondBody.color { //if the colors collide, remove small one from the scene
        label.text = "\(numPoints)" // points label increment
        numPoints++ //points label increment 
        secondBody.removeFromParent()
    }
    if firstBody.color != secondBody.color { // if colors don't match, call gameOver scene
    //gameOver()
    }


}

这段代码说的是我不关心2个对象是什么,如果红色物体撞到红色物体,让我们移除第二个物体。

好的,但是现在我们遇到了问题,如果第二个对象是大红色会怎么样。

我们需要对代码进行编程,以便第二个对象始终为红色。这是类别的来源。类别是该对象应该是什么的整数表示。

如果我们使较大的对象类别蒙版低于我们较小的对象类别蒙版,我们可以编写如下公式:

let firstBody = ((contact.bodyA.categoryBitMask <= contact.bodyB.categoryBitMask) ? contact.bodyA.node : contactBodyB.node) as! SKSpriteNode // registering as big blue square
let secondBody = ((contact.bodyA.categoryBitMask <= contact.bodyB.categoryBitMask) ? contact.bodyB.node : contactBodyA.node) as! SKSpriteNode // registering as little blue square

如果A&lt; = B则让firstBody成为bodyA的节点,或者如果A&gt;则让bodyB成为bodyA的节点。如果A&lt; = B,则让secondBody成为bodyB的节点,如果A&gt;则使bodyA成为bodyA的节点。乙

现在你已经完成了categoryBitMasks的方式,这是不可能的。您必须创建位掩码,以便较大的对象和较小的对象不共享相同的掩码。

现在我们保留了订单,因此我们的代码确切地说明了我们正在寻找的内容。

如果你想要删除什么颜色的打印件,那么我们之后只是做一个条件来检查颜色。请参阅下面的最终结果。

func didBeginContact() {
    let firstBody = ((contact.bodyA.categoryBitMask <= contact.bodyB.categoryBitMask) ? contact.bodyA.node : contactBodyB.node) as! SKSpriteNode // registering as big blue square
    let secondBody = ((contact.bodyA.categoryBitMask <= contact.bodyB.categoryBitMask) ? contact.bodyB.node : contactBodyA.node) as! SKSpriteNode // registering as little blue square

    if firstBody.color == secondBody.color { //if the colors collide, remove small one from the scene
        label.text = "\(numPoints)" // points label increment
        numPoints++ //points label increment 

        if(secondBody.color == UIColor.greenColor())
        {
           print("Green was removed")
        }

        if(secondBody.color == UIColor.redColor())
        {
           print("Red was removed")
        }

        if(secondBody.color == UIColor.blueColor())
        {
           print("Blue was removed")
        }

        if(secondBody.color == UIColor.yellowColor())
        {
           print("Yellow was removed")
        }


        secondBody.removeFromParent()
    }
    if firstBody.color != secondBody.color { // if colors don't match, call gameOver scene
    //gameOver()
    }




}

现在请记住,你从不打扰检查正在发生的碰撞类型,所以如果你决定在将来添加中等红色会导致颜色匹配,那么这将导致问题。因为在目前的状态下,我们只关心红色是红色的,我们不关心它是中等还是小。因此,在进行任何处理之前,您需要使用我们在您的另一个问题中讨论的切换方法来首先检查发生了什么类型的碰撞:

func didBeginContact() {
    let firstBody = ((contact.bodyA.categoryBitMask <= contact.bodyB.categoryBitMask) ? contact.bodyA.node : contactBodyB.node) as! SKSpriteNode // registering as big blue square
    let secondBody = ((contact.bodyA.categoryBitMask <= contact.bodyB.categoryBitMask) ? contact.bodyB.node : contactBodyA.node) as! SKSpriteNode // registering as little blue square


    switch(firstBody.categoryBitMask | secondBody.categoryBitMask)
    {
        case BigObject | SmallObject:

        if firstBody.color == secondBody.color { //if the colors collide, remove small one from the scene
            label.text = "\(numPoints)" // points label increment
            numPoints++ //points label increment 

            if(secondBody.color == UIColor.greenColor())
            {
               print("Green was removed")
            }

            if(secondBody.color == UIColor.redColor())
            {
               print("Red was removed")
            }

            if(secondBody.color == UIColor.blueColor())
            {
               print("Blue was removed")
            }

            if(secondBody.color == UIColor.yellowColor())
            {
               print("Yellow was removed")
            } 


            secondBody.removeFromParent()
        }
        if firstBody.color != secondBody.color { // if colors don't match, call gameOver scene
        //gameOver()
        }

        default:()
    }




}