SpriteKit 无法识别联系人

SpriteKit won't recognise contact

下面是我的代码,由于某种原因无法识别两个精灵之间的接触,在这种情况下,忍者和左墙或右墙。所以我的问题是我错过了什么?我添加了碰撞类别并相应地分配了它们

func didBegin(_ contact: SKPhysicsContact) {

    let nodeB = contact.bodyB.node!

    if nodeB.name == "RIGHT_WALL"  {

        print("right wall touched")
        RightWallTouched = true
        self.CurrentScore = self.CurrentScore + 1

    }
    if nodeB.name == "LEFT_WALL" {

        print("left wall touched")
        RightWallTouched = false
        self.CurrentScore = self.CurrentScore + 1

    }

    self.CurrentScoreLabel.text = "\(self.CurrentScore)"

    if nodeB.name == "SPIKE" {

        self.GameStarted = false
        if(CurrentScore > HighScore){
            defaults.set(CurrentScore, forKey: self.HighScoreStorageKey)
            defaults.synchronize()
            self.HighScoreLabel.text = "\(self.defaults.integer(forKey: self.HighScoreStorageKey))"
        }
        endGame()
    }
}




func CreateNinja(){

    let ninjaTexture = SKTexture(imageNamed: "ninja-right.png")
    ninjaTexture.filteringMode = .nearest
    self.ninja = SKSpriteNode(texture: ninjaTexture)
    self.ninja!.physicsBody = SKPhysicsBody(texture: ninjaTexture, size: ninja!.size)
    self.ninja?.name = "NINJA"
    self.ninja!.physicsBody?.isDynamic = false
    self.ninja!.physicsBody?.allowsRotation = false
    self.ninja!.physicsBody?.restitution = 0.6
    self.ninja!.physicsBody?.mass = 0.430 // m = 430g
    self.ninja!.position = CGPoint(x: self.frame.size.width / 2 , y: self.frame.size.height/5)
    self.ninja!.physicsBody?.categoryBitMask = ninjaCollisionCategory
    self.ninja!.physicsBody?.contactTestBitMask = 0
    self.ninja!.physicsBody?.collisionBitMask = wallCollisionCategory
    self.addChild(self.ninja!)
}


func CreateWall(){

    let topwall = SKSpriteNode()
    topwall.name = "TOP_WALL"
    topwall.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: self.frame.size.width, height: 5))
    topwall.physicsBody?.categoryBitMask = wallCollisionCategory
    topwall.physicsBody?.isDynamic = false
    topwall.physicsBody?.restitution = 0.6
    topwall.position = CGPoint(x: self.frame.size.width / 2.0 , y: self.frame.size.height)
    topwall.physicsBody?.friction = 0
    topwall.zPosition = 4
    self.addChild(topwall)

    let leftwall = SKSpriteNode(color: UIColor.black, size: CGSize(width: 20, height: self.frame.size.height))
    leftwall.name = "LEFT_WALL"
    leftwall.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: 20, height: self.frame.size.height))
    leftwall.physicsBody?.categoryBitMask = wallCollisionCategory
    leftwall.physicsBody?.contactTestBitMask = 0
    leftwall.physicsBody?.isDynamic = false
    leftwall.position = CGPoint(x: 0 , y: self.frame.size.height / 2.0)
    leftwall.zPosition = 4
    leftwall.physicsBody?.restitution = 1.0
    leftwall.physicsBody?.friction = 0
    self.addChild(leftwall)

    let rightwall = SKSpriteNode(color: UIColor.black, size: CGSize(width: 20, height: self.frame.size.height))
    rightwall.name = "RIGHT_WALL"
    rightwall.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: 20, height: self.frame.size.height))
    rightwall.physicsBody?.categoryBitMask = wallCollisionCategory
    rightwall.physicsBody?.contactTestBitMask = 0
    rightwall.physicsBody?.isDynamic = false
    rightwall.physicsBody?.restitution = 1.0
    rightwall.physicsBody?.friction = 0
    rightwall.position = CGPoint(x: self.frame.size.width , y: self.frame.size.height / 2.0)
    rightwall.zPosition = 4
    self.addChild(rightwall)
}

一个更常见的实现碰撞功能的方法是这样的

func didBegin(_ contact: SKPhysicsContact) {
     let firstBody: SKPhysicsBody
     let secondBody: SKPhysicsBody

     if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
         firstBody = contact.bodyA
         secondBody = contact.bodyB
     } else {
         firstBody = contact.bodyB
         secondBody = contact.bodyA
     }

     // Ninja hit wall or wall hit ninja
     if (firstBody.categoryBitMask == ninjaCollisionCategory) && (secondBody.categoryBitMask == wallCollisionCategory) {

         // Do something for all walls
         ...

         // you can also check the name for some specific wall e.g.
         if secondBody.node?.name == "RIGHT_WALL" {
               // hit right wall
         }
     }
}

你还需要在didMoveToView中设置delegate

physicsWorld.contactDelegate = self

并且可能应该将您的忍者精灵物理体设置为动态

ninja?.physicsBody?.isDynamic = true // You can also remove this line as its set to true by default

最后,作为一种好的做法,请尝试遵循 Swift 准则,您的函数和属性应以小写字母而不是大写字母开头,例如

var currentScore = 0
func createNinja() { ... }

希望对您有所帮助