Testing contact between SkSpriteNodes with the same name problem

How can I do something when contacts between two lines in my game occur? Everytime a touch on the screen occurs this code runs and a new line is spawned.

func spawnLine() {
      
        let constantGravityVector = vector_float3(x: 0, y: -15, z: 0)
        let constantGravityNode = SKFieldNode.velocityField(withVector: constantGravityVector)
      
        print("Drop")
        // Create line
        let line = SKSpriteNode(imageNamed: "Line")
      
        line.position = CGPoint(x: self.size.width/2, y: self.size.height * 0.8)
        line.zPosition = 1
        line.name = "line"
      
        line.physicsBody?.affectedByGravity = false
        line.physicsBody?.isDynamic = true
        line.physicsBody?.categoryBitMask = PhysicsCategory.LineContact
        line.physicsBody?.collisionBitMask = PhysicsCategory.CircleContact
        line.physicsBody?.contactTestBitMask = PhysicsCategory.CircleContact | PhysicsCategory.LineContact
        line.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: line.size.width, height: line.size.height))
        line.addChild(constantGravityNode)
      
        self.addChild(line)
      
    }


As of now this is how I have the code to test if a contact occurs.

func didBegin(_ contact: SKPhysicsContact) {
       
       
       
        if contact.bodyA.node?.name == "line" && contact.bodyB.node?.name == "line" {
            print("Line Contact")
        }
       
       
        if contact.bodyA.node?.name == "line" && contact.bodyB.node?.name == "circle" {
            print("contact a")
           
            // Joint the line to the circle
           
            scene?.physicsWorld.add(SKPhysicsJointFixed.joint(withBodyA: contact.bodyA, bodyB: contact.bodyB, anchor: contact.contactPoint))
        }
        else if contact.bodyB.node?.name == "line" && contact.bodyA.node?.name == "circle" {
            print("contact b")
           
            // Joint the line to the circle
           
            scene?.physicsWorld.add(SKPhysicsJointFixed.joint(withBodyA: contact.bodyA, bodyB: contact.bodyB, anchor: contact.contactPoint))
        }
       
    }


This code works for for checking between a line and circle. However, I have the lines 5-7 to test if contact between line SKSpriteNodes occurs, but it doesn't work. So, how do I get this part of the code to run something when two of the line SKSpriteNodes come into contact?


Thanks for any help.

Accepted Reply

Well, you appear to be doing things in the wrong order in spawnLine. You don't create the physics body (and associate it with the sprite node) until line 19. That means all of the references to the physics body in lines 14-18 are nil, and so the contact masks don't actually get set up. (All of lines 14-18 do nothing.)


I strongly recommend you do not use the pattern of carrying optional values through sequences of code like this. In fact, you require a physics body to exist, so why write code that allows that it might not exist (the "?" operators in lines 14-18). Instead, do something like this:


let physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: line.size.width, height: line.size.height))

physicsBody.affectedByGravity = false
physicsBody.isDynamic = true
physicsBody.categoryBitMask = PhysicsCategory.LineContact
physicsBody.collisionBitMask = PhysicsCategory.CircleContact
physicsBody.contactTestBitMask = PhysicsCategory.CircleContact | PhysicsCategory.LineContact

line.physicsBody = physicsBody


See? No optionals!

Replies

Well, you appear to be doing things in the wrong order in spawnLine. You don't create the physics body (and associate it with the sprite node) until line 19. That means all of the references to the physics body in lines 14-18 are nil, and so the contact masks don't actually get set up. (All of lines 14-18 do nothing.)


I strongly recommend you do not use the pattern of carrying optional values through sequences of code like this. In fact, you require a physics body to exist, so why write code that allows that it might not exist (the "?" operators in lines 14-18). Instead, do something like this:


let physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: line.size.width, height: line.size.height))

physicsBody.affectedByGravity = false
physicsBody.isDynamic = true
physicsBody.categoryBitMask = PhysicsCategory.LineContact
physicsBody.collisionBitMask = PhysicsCategory.CircleContact
physicsBody.contactTestBitMask = PhysicsCategory.CircleContact | PhysicsCategory.LineContact

line.physicsBody = physicsBody


See? No optionals!