0

现在,我有一块从屏幕上掉下来的砖头。当它击中我的方格时,什么也没有发生。如下图所示,我有四个三角形在同一个位置组成一个正方形,但不透明度较低。这是为了帮助区分接触到正方形的哪一侧。然而,没有任何东西重生或消失会赢得砖块击中三角形(构成正方形的三角形)。

游戏画面

    func spawnBrick()  {
            let randomFunc = [self.spawnbrickTop, self.spawnbrickBottom, self.spawnbrickLeft, self.spawnbrickRight]
            let randomResult = Int(arc4random_uniform(UInt32(randomFunc.count)))
            randomFunc[randomResult]()
        }



    func spawnbrickTop() {

        brickTop.size = CGSize(width: 210, height: 105)
        brickTop.name = "BrickTop"
        brickTop.position = CGPoint(x: frame.midX, y: frame.maxY)
        brickTop.zPosition = 1.5
        //physics stuff begins here
        brickTop.physicsBody = SKPhysicsBody(circleOfRadius: max(brickTop.size.width / 2,
                                                                 brickTop.size.height / 2))
        brickTop.physicsBody?.categoryBitMask = PhysicsCategories.brickTopCategory
        brickTop.physicsBody?.contactTestBitMask = PhysicsCategories.basicTopCategory |
        PhysicsCategories.basicBottomCategory |
        PhysicsCategories.basicLeftCategory |
        PhysicsCategories.basicRightCategory
        brickTop.physicsBody?.collisionBitMask = PhysicsCategories.none
         //bye bye physics
        self.addChild(brickTop)

    }

    func spawnbrickBottom() {

        brickBottom.size = CGSize(width: 230, height: 101)
        brickBottom.name = "BrickBottom"
        brickBottom.position = CGPoint(x: frame.midX, y: frame.maxY)
        brickBottom.zPosition = 1.5
        //physics stuff begins here
        brickBottom.physicsBody = SKPhysicsBody(circleOfRadius: max(brickBottom.size.width / 2,
                                                                    brickBottom.size.height / 2))
        brickBottom.physicsBody?.categoryBitMask = PhysicsCategories.brickBottomCategory
        brickBottom.physicsBody?.contactTestBitMask = PhysicsCategories.basicTopCategory |
        PhysicsCategories.basicBottomCategory |
        PhysicsCategories.basicLeftCategory |
        PhysicsCategories.basicRightCategory
        brickBottom.physicsBody?.collisionBitMask = PhysicsCategories.none
         //bye bye physics
        self.addChild(brickBottom)
    }

    func spawnbrickLeft() {


        brickLeft.size = CGSize(width: 170, height: 80)
        brickLeft.name = "BrickLeft"
        brickLeft.position = CGPoint(x: frame.midX, y: frame.maxY)
        brickLeft.zPosition = 1.5
        //physics stuff begins here
        brickLeft.physicsBody = SKPhysicsBody(circleOfRadius: max(brickLeft.size.width / 2,
                                                                  brickLeft.size.height / 2))
        brickLeft.physicsBody?.categoryBitMask = PhysicsCategories.brickLeftCategory
        brickLeft.physicsBody?.contactTestBitMask = PhysicsCategories.basicTopCategory |
        PhysicsCategories.basicBottomCategory |
        PhysicsCategories.basicLeftCategory |
        PhysicsCategories.basicRightCategory
        brickLeft.physicsBody?.collisionBitMask = PhysicsCategories.none
         //bye bye physics
        self.addChild(brickLeft)

    }


    func spawnbrickRight() {

        brickRight.size = CGSize(width: 140, height: 95)
        brickRight.name = "BrickRight"
        brickRight.position = CGPoint(x: frame.midX, y: frame.maxY)
        brickRight.zPosition = 1.5
        //physics stuff begins here
        brickRight.physicsBody = SKPhysicsBody(circleOfRadius: max(brickRight.size.width / 2,
                                          brickRight.size.height / 2))
        brickRight.physicsBody?.categoryBitMask = PhysicsCategories.brickRightCategory
        brickRight.physicsBody?.contactTestBitMask = PhysicsCategories.basicTopCategory |
        PhysicsCategories.basicBottomCategory |
        PhysicsCategories.basicLeftCategory |
        PhysicsCategories.basicRightCategory
        brickRight.physicsBody?.collisionBitMask = PhysicsCategories.none
         //bye bye physics
        self.addChild(brickRight)

    }


    func spawnBasicBrick() {
            basicBrick.size = CGSize(width: 200, height: 177.6)
            basicBrick.position = CGPoint(x: frame.midX, y: frame.minY + basicBrick.size.width)
            basicBrick.zPosition = 1


            basicBrick.physicsBody = SKPhysicsBody(rectangleOf: basicBrick.size)
            basicBrick.physicsBody?.categoryBitMask = PhysicsCategories.basicBrickCategory
            basicBrick.physicsBody?.isDynamic = false
            basicBrick.physicsBody?.allowsRotation = true

            addChild(basicBrick)
        }
        func spawnBasicTop() {

            basicTop.size = CGSize(width: 400, height: 400)
            basicTop.position = CGPoint(x: 230, y: 200)
            basicTop.zPosition = 1.5
            basicTop.alpha = 0.3
            basicTop.name = "BasicTop"

            //physics stuff begins here
            basicTop.physicsBody = SKPhysicsBody(rectangleOf: basicTop.size)
            basicTop.physicsBody?.categoryBitMask = PhysicsCategories.basicTopCategory
            basicTop.physicsBody?.isDynamic = false
            basicTop.physicsBody?.allowsRotation = true
            //bye bye physics


            addChild(basicTop)
        }

        func spawnBasicBottom() {

            basicBottom.size = CGSize(width: 400, height: 400)
            basicBottom.position = CGPoint(x: 230, y: 200)
            basicBottom.zPosition = 1.5
            basicBottom.alpha = 0.3
            basicBottom.name = "BasicBottom"

            //physics stuff begins here
            basicBottom.physicsBody = SKPhysicsBody(rectangleOf: basicBottom.size)
            basicBottom.physicsBody?.categoryBitMask = PhysicsCategories.basicBottomCategory
            basicBottom.physicsBody?.isDynamic = false
            //bye bye physics


            addChild(basicBottom)
        }
        func spawnBasicLeft() {

            basicLeft.size = CGSize(width: 400, height: 400)
            basicLeft.position = CGPoint(x: 230, y: 200)
            basicLeft.zPosition = 1.5
            basicLeft.alpha = 0.3
            basicLeft.name = "BasicLeft"

            //physics stuff begins here
            basicLeft.physicsBody = SKPhysicsBody(rectangleOf: basicLeft.size)
            basicLeft.physicsBody?.categoryBitMask = PhysicsCategories.basicLeftCategory
            basicLeft.physicsBody?.isDynamic = false
            //bye bye physics


            addChild(basicLeft)
        }

        func spawnBasicRight() {

            basicRight.size = CGSize(width: 400, height: 400)
            basicRight.position = CGPoint(x: 230, y: 200)
            basicRight.zPosition = 1.5
            basicRight.alpha = 0.3
            basicRight.name = "BasicRight"

            //physics stuff begins here
            basicRight.physicsBody = SKPhysicsBody(rectangleOf: basicRight.size)
            basicRight.physicsBody?.categoryBitMask = PhysicsCategories.basicRightCategory
            basicRight.physicsBody?.isDynamic = false
            //bye bye physics


            addChild(basicRight)
        }



extension GameScene: SKPhysicsContactDelegate {

    func didBegin(_ contact: SKPhysicsContact) {
        //01
        //10
        //11
        let contactMask = contact.bodyA.categoryBitMask |
            contact.bodyB.categoryBitMask

        if contactMask == PhysicsCategories.brickTopCategory |
            (PhysicsCategories.basicTopCategory) {
            if let brickTop = contact.bodyA.node?.name == "BrickTop" ? contact.bodyA.node
                as? SKSpriteNode : contact.bodyB.node as? SKSpriteNode {
            if contact.bodyA.node?.name == "BrickTop" &&
               contact.bodyB.node?.name == "BasicTop" {

                    print("Correct!")
                    brickTop.run(SKAction.fadeOut(withDuration: 0.05), completion: {
                        self.brickTop.removeFromParent()
                        self.spawnBrick()
                    })
            }
    }
           else if contactMask == PhysicsCategories.brickBottomCategory |
                    (PhysicsCategories.basicBottomCategory) {
            if let brickBottom = contact.bodyA.node?.name == "BrickBottom" ? contact.bodyA.node
            as? SKSpriteNode : contact.bodyB.node as? SKSpriteNode {
                    if contact.bodyA.node?.name == "BrickBottom" &&
                       contact.bodyB.node?.name == "BasicBottom" {

                            print("Correct!")
                            brickBottom.run(SKAction.fadeOut(withDuration: 0.05), completion: {
                                self.brickBottom.removeFromParent()
                                self.spawnBrick()
                            })
                    }
            }
       else if contactMask == PhysicsCategories.brickLeftCategory |
                (PhysicsCategories.basicLeftCategory) {
        if let brickLeft = contact.bodyA.node?.name == "BrickLeft" ? contact.bodyA.node
        as? SKSpriteNode : contact.bodyB.node as? SKSpriteNode {
                if contact.bodyA.node?.name == "BrickLeft" &&
                   contact.bodyB.node?.name == "BasicLeft" {

                        print("Correct!")
                        brickLeft.run(SKAction.fadeOut(withDuration: 0.05), completion: {
                            self.brickLeft.removeFromParent()
                            self.spawnBrick()
                        })
                }
        }
       else if contactMask == PhysicsCategories.brickRightCategory |
                (PhysicsCategories.basicRightCategory) {
        if let brickRight = contact.bodyA.node?.name == "BrickRight" ? contact.bodyA.node
        as? SKSpriteNode : contact.bodyB.node as? SKSpriteNode {
                if contact.bodyA.node?.name == "BrickRight" &&
                   contact.bodyB.node?.name == "BasicRight" {

                        print("Correct!")
                        brickRight.run(SKAction.fadeOut(withDuration: 0.05), completion: {
                            self.brickRight.removeFromParent()
                            self.spawnBrick()
                        })
                }
        }
        else {
            gameOver()
        }
  }
 }
}
}
}
}


enum PhysicsCategories {
    static let none: UInt32 = 0
    static let brickCategory: UInt32 = 1//01
    static let brickTopCategory: UInt32 = 1 //01
    static let brickBottomCategory: UInt32 = 1//01
    static let brickLeftCategory: UInt32 = 1//01
    static let brickRightCategory: UInt32 = 1//01

    static let basicTopCategory: UInt32 = 1 //10; shifts all bits to the left
    static let basicBottomCategory: UInt32 = 1 //10; shifts all bits to the left
    static let basicLeftCategory: UInt32 = 1 //10; shifts all bits to the left
    static let basicRightCategory: UInt32 = 1 //10; shifts all bits to the left

    static let basicBrickCategory: UInt32 = 1
}
4

1 回答 1

0

问题可能是这样的:

brickTop.physicsBody?.contactTestBitMask = PhysicsCategories.basicTopCategory
brickTop.physicsBody?.contactTestBitMask = PhysicsCategories.basicBottomCategory
brickTop.physicsBody?.contactTestBitMask = PhysicsCategories.basicLeftCategory
brickTop.physicsBody?.contactTestBitMask = PhysicsCategories.basicRightCategory

在此代码中,联系人位掩码最终只是 basicRight。你想把它们结合起来。这是假设您正确设置了开始的类别(如 1、2、4、8 等)

你希望它更像这样:


brickTop.physicsBody?.contactTestBitMask = PhysicsCategories.basicTopCategory |
   PhysicsCategories.basicBottomCategory |
   PhysicsCategories.basicLeftCategory |
   PhysicsCategories.basicRightCategory

这是应该如何工作的

  1. 你的场景中有一堆节点
  2. 您将它们分组到具有相似行为的类别中
  3. 您为每个类别创建一个类别枚举/值作为掩码(1、2、4 等)中的一个位,即 (0x1 << 0, 0x1 << 1, 0x1 << 2)
  4. 您将节点分类(|用于组合类别值)
  5. 您设置 contactTest 和 collisionDetect 位掩码(|用于组合类别值)

我不知道你的游戏应该如何工作,但你的代码有几处让你感觉很奇怪。

  1. 您对不同的类别使用相同的数字
  2. 您不会将它们组合成位掩码。

想象一下我有乒乓球游戏。我想检测球何时击中

  1. 反弹它的侧壁
  2. 屏幕顶部和底部记录输出
  3. 用来弹跳它的桨

节点

  1. 左墙
  2. 右墙
  3. 底部
  4. 最佳
  5. 顶桨
  6. 底部桨
  7. 玩家 1 得分
  8. 玩家 2 得分

类别(这只是一个例子——它不是唯一的方法)

  1. 类别无:0
  2. CategoryGamePiece: 1
  3. CategoryOutDetector: 2
  4. CategoryNonInteractive:4(用于得分节点)

球从桨叶和侧壁反弹。它还与顶部和底部的隐形探测器相互作用。它分为两类(使用|

ball.categoryBitMask = CategoryGamePiece | CategoryOutDetector
ball.collisionBitMask = CategoryGamePiece
ball.contactTestBitMask = CategoryOutDetector

球拍和侧壁仅作为游戏棋子与球相互作用(碰撞)

paddleTop.categoryBitMask = CategoryGamePiece
paddleTop.collisionBitMask = CategoryGamePiece
paddleTop.contactTestBitMask = CategoryNone

leftWall.categoryBitMask = CategoryGamePiece
leftWall.collisionBitMask = CategoryGamePiece
leftWall.contactTestBitMask = CategoryNone

底部仅与球交互作为接触测试(不改变其运动)

bottomOut.categoryBitMask = CategoryOutDetector
bottomOut.collisionBitMask = CategoryNone
bottomOut.contactTestBitMask = CategoryOutDetector
于 2020-02-25T23:48:16.587 回答