SKPhysicsContact Not Detecting categoryBitMask Col

2019-05-22 01:36发布

问题:

So I have my "Floor.swift" class below which is basically a bunch of walls. I have objects coming from the top of the screen and once the Floor and SKSpriteNodes collide, I'd like the SKSpriteNode to be removed. Below is my Floor class.

import Foundation
import SpriteKit

    class Floor: SKNode {
        override init() {
            super.init()

            let leftWall = SKSpriteNode(color: UIColor.brown, size: CGSize(width: 5, height: 50))
            leftWall.position = CGPoint(x: 0, y: 50)
            leftWall.physicsBody = SKPhysicsBody(rectangleOf: leftWall.size)
            leftWall.physicsBody!.isDynamic = false
            self.addChild(leftWall)

            let rightWall = SKSpriteNode(color: UIColor.brown, size: CGSize(width: 5, height: 50))
            rightWall.position = CGPoint(x: 375, y: 50)
            rightWall.physicsBody = SKPhysicsBody(rectangleOf: rightWall.size)
            rightWall.physicsBody!.isDynamic = false
            self.addChild(rightWall)

            let bottomWall = SKSpriteNode(color: UIColor.brown, size: CGSize(width: 500, height: 10))
            bottomWall.position = CGPoint(x: 150, y: -5)
            bottomWall.physicsBody = SKPhysicsBody(rectangleOf: bottomWall.size)
            bottomWall.physicsBody!.isDynamic = false
            self.addChild(bottomWall)

            // Set the bit mask properties
            self.physicsBody?.categoryBitMask = floorCategory
            self.physicsBody?.contactTestBitMask = objectCategory | pointCategory | lifeCategory
            self.physicsBody?.collisionBitMask = dodgeCategory
        }

        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemted")
        }
    } 

Then in my GameScene class under "func didBegin(_ contact: SKPhysicsContact)" I wrote:

 if (contact.bodyA.categoryBitMask == floorCategory) && (contact.bodyB.contactTestBitMask == objectCategory | pointCategory | lifeCategory) {
              contact.bodyB.node!.removeFromParent()
              print("COLLISION")
}

But for some reason I'm not getting any detection what's so ever. I made my "Floor" class be a "contactTestBitMask" on each class of my objectCategory, pointCategory, lifeCategory. What am I doing wrong!? My other collisions are detected but not this one.

回答1:

Your leftWall, rightWall and bottomWall have the default contactTest and collision bit masks, so will collide with everything and generate contacts with nothing. Except they all have their isDynamic property set to false, so they can’t collide with or contact anything (although other things can collide and contact them if those other things have isDynamic set to true).

But this is probably what you want (Floors and walls are usually not dynamic). I suspect the real problem is that objects of Floor class won’t have a physics body, unless you initialise it somewhere else. You have these lines:

self.physicsBody?.categoryBitMask = ... self.physicsBody?.contactTestBitMask = ... self.physicsBody?.collisionBitMask = ...

but you haven't actually created self.physicsBody. Your code would crash except you’ve used optional chaining (self,phyicsBody?) and so Swift gets to the ‘?’ and says “Oh - it’s optional and doesn’t exist. I’ll just stop here then”

At the very least, try creating a physics body for your Floor object using the physics bodies of the 3 wall objects:

Self.physicsBody = SKPhysicsBody(Bodies: [leftWall.physicsBody, rightWall.PhysicsBoidy, bottomWall.physicsBody])

(SKPhysicsBody has an initialiser that takes an array of physics bodies to create a new physics body).