Swift: No contact detection between nodes

徘徊边缘 提交于 2020-03-23 08:03:10

问题


Issue

This is my code for my game. A brick falls and hits a side of a square. To differentiate what side is hit, four triangles are spawned that make the square. They are invisible from a low opacity. I am not receiving any contact between the brick node and the triangle node. The brick piece just falls right through the square. Any help?

Game Code

import SpriteKit


class GameScene: SKScene {


    let basicTop = SKSpriteNode(imageNamed: "basic top");
    let basicBottom = SKSpriteNode(imageNamed: "basic bottom");
    let basicLeft = SKSpriteNode(imageNamed: "basic left");
    let basicRight = SKSpriteNode(imageNamed: "basic right");
    let brickTop = SKSpriteNode(imageNamed: "Top Side");
    let brickBottom = SKSpriteNode(imageNamed: "Bottom Side");
    let brickLeft = SKSpriteNode(imageNamed: "Left Side");
    let brickRight = SKSpriteNode(imageNamed: "Right Side copy 2");
    let basicBrick = SKSpriteNode(imageNamed: "Basic Brick")



    override func didMove(to view: SKView) {
        isUserInteractionEnabled = true
        layoutScene()

    }



    func layoutScene() {
        backgroundColor = UIColor(red: 10/255, green: 75/255, blue: 150/255, alpha: 1.0)

        spawnBrick()
        spawnBasicTop()
        spawnBasicBottom()
        spawnBasicLeft()
        spawnBasicRight()
        backgroundScene()
        spawnBasicBrick()
        setupPhysics()

    }

    func setupPhysics() {
        physicsWorld.gravity = CGVector(dx: 0.0, dy: -0.1)
        physicsWorld.contactDelegate = self
    }

    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
        //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
        addChild(brickTop)

    }

    func spawnbrickBottom() {

        brickBottom.size = CGSize(width: 150, height: 101)
        brickBottom.name = "BrickBottom"
        brickBottom.position = CGPoint(x: frame.midX, y: frame.maxY)
        brickBottom.zPosition = 1
        //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
        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
        //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
        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
        //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
        addChild(brickRight)

    }





    func turnBasicTop() {
        basicTop.run(SKAction.rotate(byAngle: .pi/2, duration: 0.25))
    }

    func turnBasicBottom() {
        basicBottom.run(SKAction.rotate(byAngle: .pi/2, duration: 0.25))
    }

    func turnBasicLeft() {
        basicLeft.run(SKAction.rotate(byAngle: .pi/2, duration: 0.25))
    }

    func turnBasicRight() {
        basicRight.run(SKAction.rotate(byAngle: .pi/2, duration: 0.25))
    }

    func turnBasicBrick() {
        basicBrick.run(SKAction.rotate(byAngle: .pi/2, duration: 0.25))
    }
    func gameOver() {
        print("Game Over!")
    }



      override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
            turnBasicTop()
            turnBasicBottom()
            turnBasicLeft()
            turnBasicRight()
            turnBasicBrick()
        }

    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
        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
        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
        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
        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)
    }


    func backgroundScene() {
    let constructionSite = SKSpriteNode(imageNamed: "Background Image")
        constructionSite.size = frame.size
        constructionSite.position = CGPoint(x: frame.midX, y: frame.midY)
        constructionSite.zPosition = -1
        addChild(constructionSite)
    }
}

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 brickTop == basicTop {

                    print("Correct!")
                    brickTop.run(SKAction.fadeOut(withDuration: 0.05), completion: {
                        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 brickBottom == basicBottom {

                            print("Correct!")
                        brickBottom.run(SKAction.fadeOut(withDuration: 0.05), completion: {
                                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 brickLeft == basicLeft {

                        print("Correct!")
                brickLeft.run(SKAction.fadeOut(withDuration: 0.05), completion: {
                            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 brickRight == basicRight {

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

Settings File:

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

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

    static let basicBrickCategory: UInt32 = 0x1
}

来源:https://stackoverflow.com/questions/60477859/swift-no-contact-detection-between-nodes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!