0

我正在尝试在 Swift 中使用 Spritekit 编写游戏。目的是逃脱他的性格迎面而来的矩形。现在我在使用 SKPhysicsContactDelegate (didBegin ()) 方法时犯了一个错误,因此无法识别图形与其中一个矩形的接触。有人可以帮我找出错误吗?这不是重复的,因为这次我使用了不同的代码!

    import SpriteKit

    struct PhysicsCategory {
        static let none      : UInt32 = 0
        static let all       : UInt32 = UInt32.max
        static let rechteck  : UInt32 = 0b1       // 1
        static let figur     : UInt32 = 0b10      // 2
    }

    class PlayScene: SKScene, SKPhysicsContactDelegate{

        let figur = SKSpriteNode(imageNamed: "Punkt.jpg")

        @objc func addRechteck(){
            let rechteckRechts = SKSpriteNode(imageNamed: "Rechteck.gif")
            rechteckRechts.physicsBody = SKPhysicsBody(rectangleOf: rechteckRechts.size) // 1
            rechteckRechts.physicsBody?.isDynamic = true // 2
            rechteckRechts.physicsBody?.categoryBitMask = PhysicsCategory.rechteck // 3
            rechteckRechts.physicsBody?.contactTestBitMask = PhysicsCategory.rechteck // 4


    rechteckRechts.physicsBody?.collisionBitMask = PhysicsCategory.none // 5

        let rechteckLinks = SKSpriteNode(imageNamed: "Rechteck.gif")
        rechteckLinks.physicsBody = SKPhysicsBody(rectangleOf: rechteckLinks.size) // 1
        rechteckLinks.physicsBody?.isDynamic = true // 2
        rechteckLinks.physicsBody?.categoryBitMask = PhysicsCategory.rechteck // 3
        rechteckLinks.physicsBody?.contactTestBitMask = PhysicsCategory.rechteck // 4
        rechteckLinks.physicsBody?.collisionBitMask = PhysicsCategory.none // 5

        let groesse = arc4random_uniform(5)+1
        print(groesse)

        switch groesse {
        case 1:
            rechteckLinks.xScale = 0.5
            rechteckRechts.xScale = 1.5
        case 2:
            rechteckLinks.xScale = 1.5
            rechteckRechts.xScale = 0.5
        case 3:
            rechteckLinks.xScale = 1
            rechteckRechts.xScale = 1
        case 4:
            rechteckLinks.xScale = 1.25
            rechteckRechts.xScale = 0.75
        case 5:
            rechteckLinks.xScale = 0.75
            rechteckRechts.xScale = 1.25
        default:
            print("Fehler in der Wahrscheinlichkeit!!!")
        }
        rechteckRechts.position = CGPoint(x: frame.minX + (rechteckRechts.size.width / 2), y: frame.maxY)
        rechteckLinks.position = CGPoint(x: frame.maxX - (rechteckLinks.size.width / 2), y: frame.maxY)

        let moveDown = SKAction.moveBy(x: 0, y: -5000, duration: 20.0)
        rechteckLinks.run(moveDown)
        rechteckRechts.run(moveDown)

        self.addChild(rechteckRechts)
        self.addChild(rechteckLinks)
    }

    override func didMove(to view: SKView) {
        physicsWorld.gravity = .zero
        physicsWorld.contactDelegate = self

        figur.xScale = 0.4
        figur.yScale = 0.4
        figur.position = CGPoint(x: frame.midX, y: frame.maxY / 4)
        figur.physicsBody = SKPhysicsBody(rectangleOf: figur.size)
        figur.physicsBody?.isDynamic = true
        figur.physicsBody?.categoryBitMask = PhysicsCategory.figur
        figur.physicsBody?.contactTestBitMask = PhysicsCategory.rechteck
        figur.physicsBody?.collisionBitMask = PhysicsCategory.none
        figur.physicsBody?.usesPreciseCollisionDetection = true
        self.addChild(figur)

        self.backgroundColor = SKColor.white

        let wait1 = SKAction.wait(forDuration: 3)
        let timer = SKAction.repeatForever(SKAction.sequence([wait1, SKAction.run {
            self.addRechteck()
            }]))
        self.run(timer, withKey: "addRechteck")

    }


    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch in (touches ){
            let location = touch.location(in: self)
            if figur.contains(location){
                figur.position = location
            }
        }
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch in (touches ) {
            let location = touch.location(in: self)
            if figur.contains(location){
                figur.position = location
            }
        }
    }
}
func figurDidColissionWithRectangle(figur: SKSpriteNode, rechteck: SKSpriteNode) {
    print("Hit")
    figur.removeFromParent()
    rechteck.removeFromParent()
}

extension GameScene: SKPhysicsContactDelegate {
    func didBegin(_ contact: SKPhysicsContact) {
        // 1
        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
        }

        // 2
        if ((firstBody.categoryBitMask & PhysicsCategory.rechteck != 0) &&
            (secondBody.categoryBitMask & PhysicsCategory.figur != 0)) {
            if let rechteck = firstBody.node as? SKSpriteNode,
                let figur = secondBody.node as? SKSpriteNode {
                figurDidColissionWithRectangle(figur: figur, rechteck: rechteck)
            }
        }
    }
}
4

1 回答 1

0

在 addRecktech() 方法中,您已经告诉 rechteckRechts 的物理体只测试与自身的接触:

rechteckRechts.physicsBody?.contactTestBitMask = PhysicsCategory.rechteck //4

我建议将这行代码更改为以下代码,告诉它测试与 figur 的联系:

rechteckRechts.physicsBody?.contactTestBitMask = PhysicsCategory.figur //4

我相信,因为在您当前的代码中,rechTeck 和 figur 之间的联系只有一个“单向”测试,所以会错过一些联系事件。

于 2018-08-17T09:08:58.990 回答