0
votes

I have 3 collision types right now. "Head", "Body", and "Food".

The head collides with the food fine. The "Head" and "Body" are a SKNode and instances of the "SnakeBodyUnit" class. The "Head", however, does not fire when trying to collide with a "Body" object. Again, the "Head" collides fine with the "Food" SKSpriteNode. The "Food" class is separate.

Here are the 2 classes: SnakeBodyUnit:

class SnakeBodyUnit : SKNode {

var bodyDir: Direction?
var id = -1
var partX = -1
var partY = -1
var bodyT = -1

var unitHolder: SKSpriteNode?

init(size: CGSize, gap: CGFloat, bodyType: Int) {
    super.init()

    bodyT = bodyType

    let xPos = (size.width - (size.width * gap)) / 2
    let yPos = (size.height - (size.height * gap)) / 2
    let reducedSize = size.width*gap

    unitHolder = SKSpriteNode()
    unitHolder!.position = CGPoint(x:xPos, y:yPos);
    unitHolder!.size = CGSize(width: (size.width * gap), height: (size.height * gap))

    if (bodyT == 0) {
        //head
        unitHolder!.color = UIColor(
            red: 184/255,
            green: 252/255,
            blue: 101/255,
            alpha: 1.0)


        self.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(reducedSize/2, reducedSize/2), center: CGPointMake(reducedSize/2, reducedSize/2))
        self.physicsBody?.affectedByGravity = false
        self.physicsBody?.categoryBitMask = ColliderType.Head
        self.physicsBody?.dynamic = false
        self.physicsBody?.contactTestBitMask = ColliderType.Food | ColliderType.Body

    } else if (bodyT == 1) {
        //body part
        unitHolder!.color = UIColor(
            red: 52/255,
            green: 229/255,
            blue: 253/255,
            alpha: 1.0)

        self.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(reducedSize/2, reducedSize/2), center: CGPointMake(reducedSize/2, reducedSize/2))
        self.physicsBody?.affectedByGravity = false
        self.physicsBody?.categoryBitMask = ColliderType.Body
        self.physicsBody?.dynamic = false


    } else if (bodyT == 2) {
        //static corner
        unitHolder!.color = UIColor(
            red: 52/255,
            green: 229/255,
            blue: 0/255,
            alpha: 1.0)
    }

    unitHolder!.anchorPoint = CGPoint(x: 0, y: 0)

    self.addChild(unitHolder!)


}

required init?(coder aDecoder: NSCoder) {
    fatalError("init coder not implemented")
}

}

Here is the food class where the collision works fine:

class Food : SKSpriteNode {

func createFood(bodyamount: CGFloat, gap: CGFloat) {

    self.size = CGSizeMake(bodyamount * gap, bodyamount * gap)

    self.color = UIColor(
    red: 184/255,
    green: 252/255,
    blue: 101/255,
    alpha: 1.0)

    let reducedSize = bodyamount * gap
    self.position = CGPoint(x: bodyamount, y: reducedSize/2)
    self.zRotation = 45.0 * CGFloat(M_PI) / 180


    self.physicsBody = SKPhysicsBody(rectangleOfSize: self.size, center: CGPointMake(reducedSize/2, reducedSize/2))
    self.physicsBody?.affectedByGravity = false
    self.physicsBody?.categoryBitMask = ColliderType.Food


    self.anchorPoint = CGPoint(x: 0, y: 0)
}

} //these are in a struct called ColliderType

static let Head:          UInt32 = 0
static let Food:          UInt32 = 0b1
static let Body:          UInt32 = 0b10
2
Are you checking the right categories? Collision and contact are 2 different things in sprite kitKnight0fDragon
i don't need them to physically collide. i just want to update the main scene in the didBeginContact function. the categoryBitMask ids are right. i get didBeginContact to fire in the "Head" to "Food" case which is what is confusing currently. "Head" to "Body" should work too.josh k
can you list your collider enumKnight0fDragon
Please show your bitmasks !ColdSteel
Please reffer to this SO question and make sure your bitmasks are set correctly, there is an example as well ! stackoverflow.com/questions/19473598/…ColdSteel

2 Answers

0
votes

You must tell to every node with what other nodes it collides. So, you must tell the head with which nodes it collides (as you already do):

self.physicsBody?.contactTestBitMask = ColliderType.Food | ColliderType.Body

But you also have to add a similar line to the body (updating the selected Collider):

self.physicsBody?.contactTestBitMask = ColliderType.Food | ColliderType.Head

and to the food:

self.physicsBody?.contactTestBitMask = ColliderType.Head | ColliderType.Body

This should fix your problem.

0
votes

The answer is to set dynamic to true in the body, and also to set the collisionBitMask to 0. here is the setup for the body class that solved it:

        self.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(reducedSize/2, reducedSize/2), center: CGPointMake(reducedSize/2, reducedSize/2))
        self.physicsBody?.affectedByGravity = false
        self.physicsBody?.categoryBitMask = ColliderType.Body
        self.physicsBody!.collisionBitMask = 0
        self.physicsBody?.dynamic = true