Search code examples
swiftsprite-kitgame-physicsskphysicsbodybitmask

SpriteKit categoryBitMask not recognized


I have three physics categories: hero, ground, and wall. My problem is that the physics category for ground is not being recognized. To troubleshoot the problem, I printed the bit masks when hero collides with wall and ground. Wall works as expected and shows its bit mask of 2. Ground, however, shows 4294967295. (It should be 4.) Ground has an edge physics body and it works because hero doesn't pass through it, it's just not being recognized as ground.

Physics categories

enum PhysicsCategory:UInt32
{
    case hero = 1
    case wall = 2
    case ground = 4
}

Ground class:

class Ground: SKSpriteNode
{
    var groundTexture = SKTexture(imageNamed: "ground4")
    var jumpWidth = CGFloat()
    var jumpCount = CGFloat(1)

    func spawn(parentNode: SKNode, position: CGPoint, size:CGSize)
    {
        parentNode.addChild(self)
        self.size = size
        self.position = position
        self.zPosition = 2
        self.anchorPoint = CGPointMake(0, 1)
        self.texture = SKTexture(imageNamed: "ground4")
        self.physicsBody?.categoryBitMask = PhysicsCategory.ground.rawValue
        self.physicsBody?.affectedByGravity = false
        self.physicsBody?.dynamic = false

        let pointTopRight = CGPoint(x: size.width, y: 0)
        self.physicsBody = SKPhysicsBody(edgeFromPoint: CGPointZero, toPoint: pointTopRight)
    }

didMoveToView:

let groundPosition = CGPoint(x: -self.size.width, y: 30)
let groundSize = CGSize(width: self.size.width * 3, height: 0) 
ground.spawn(world, position: groundPosition, size: groundSize)

didBeginContact

let firstBody = contact.bodyA
let secondBody = contact.bodyB

if firstBody.categoryBitMask == PhysicsCategory.hero.rawValue && secondBody.categoryBitMask == PhysicsCategory.ground.rawValue || firstBody.categoryBitMask == PhysicsCategory.ground.rawValue && secondBody.categoryBitMask == PhysicsCategory.hero.rawValue
        {
            print("contact with the ground!")
        }

Solution

  • You're actually creating the physicsBody after you have attempted to set the categoryBitMask. So you're attempting to set the categoryBitMask on nil...

    You just need to move that one line up...

    func spawn(parentNode: SKNode, position: CGPoint, size:CGSize)
    {
        parentNode.addChild(self)
        self.size = size
        self.position = position
        self.zPosition = 2
        self.anchorPoint = CGPointMake(0, 1)
        self.texture = SKTexture(imageNamed: "ground4")
        let pointTopRight = CGPoint(x: size.width, y: 0)
    
        self.physicsBody = SKPhysicsBody(edgeFromPoint: CGPointZero, toPoint: pointTopRight)
    
        self.physicsBody?.categoryBitMask = PhysicsCategory.ground.rawValue
        self.physicsBody?.affectedByGravity = false
        self.physicsBody?.dynamic = false
    }