1
votes

I have two nodes, one "cat" and one "rat", but for some reason I can't get their collision to be detected. I'm using this method for masks:

enum CollisionTypes: UInt32 {
    case holder      = 1
    case chef        = 2
    case powerups    = 4
    case ingredients = 8
    case utensils    = 16
    case floor       = 32
    case bag         = 64
    case table       = 128
    case tip         = 256
    case rat         = 512
    case cat         = 1024
    }

Here is where I initialize their physics bodies:

    // Cat physics body, the node's name is "cat"       
     public func initializeAt(position: CGPoint) {

    sprite.position = position
    sprite.zPosition = 5
    sprite.name = "cat"
    sprite.alpha = 0.7
    scene.sceneContent.addChild(sprite)

    sprite.physicsBody = SKPhysicsBody(rectangleOf: sprite.size)
    sprite.physicsBody!.isDynamic = false
    sprite.physicsBody!.categoryBitMask    = CollisionTypes.cat.rawValue
    sprite.physicsBody!.contactTestBitMask = CollisionTypes.rat.rawValue
    sprite.physicsBody!.collisionBitMask   = CollisionTypes.rat.rawValue


    // Rat physics body, the nodes name is "rat"
    init() {
    node.name = "rat"
    node.zPosition = 5

    node.physicsBody = SKPhysicsBody(rectangleOf: node.size)
    node.physicsBody!.isDynamic = false
    node.physicsBody!.categoryBitMask = CollisionTypes.rat.rawValue
    node.physicsBody!.contactTestBitMask = CollisionTypes.cat.rawValue
    node.physicsBody!.collisionBitMask = CollisionTypes.cat.rawValue

    setupFrames()
    }

Here is my didBegin() method. However, neither of the if statements get executed and I don't know why because I am using this method for a number of other things in my project.

func didBegin(_ contact: SKPhysicsContact) {
    if let node1 = contact.bodyA.node as? SKSpriteNode,
        let node2 = contact.bodyB.node as? SKSpriteNode {

        if node1.name == "rat" && node2.name == "cat" {

            for rat in rats {
                if node1 == rat.node {
                    rat.die()
                }
            }

            Cat.shared.resetPosition()
            return
        }
        else if node1.name == "cat" && node2.name == "rat" {

            for rat in rats {
                if node2 == rat.node {
                    rat.die()
                }
            }

            Cat.shared.resetPosition()
            return
        }

If I try playing around with the contactTestBitMasks and making them something different like "ingredients", then I can see that the cat and rat are interacting with ingredients but it seems like they just wont interact with eachother.

1
You don't ever give your nodes a name, you may claim you are, but in the code provided, you do not give them a name - Knight0fDragon
Where do the node names come from? - El Tomato
I do name my nodes, I just didn't include sorry. I edited my question. But I know the names are working correctly because I've used them to test if theyre interacting with other physicsbodies - Brejuro
Where does your rats array come from? Does the rat involved in the collision have to be in this array before it can die? - Steve Ives

1 Answers

2
votes

rats and cats won't trigger contacts with each other because both have isDynamic set to false. At least one of them needs to be dynamic before a contact is triggered.

From https://developer.apple.com/documentation/spritekit/skphysicsbody

The isDynamic property controls whether a volume-based body is affected by gravity, friction, collisions with other objects, and forces or impulses you directly apply to the object.