Using multiple using didBegin contact

Hello everyone,

I would like to have so SKSpriteNodes can take care of there own contact detection.

Much like Unity have there own `OnTriggerEnter` methods on there GameObjects.
But I do not know how to achieve that in SpriteKit, some help would much appriciated

Example how I would "like" it to work:

import SpriteKit

class Ball: SKSpriteNode, SKPhysicsContactDelegate {
    
    func didBegin(_ contact: SKPhysicsContact) {
        print("INSIDE BALL: ",contact.bodyA.node?.name, contact.bodyB.node?.name)
    }
    
    init(x: Int, y: Int) {
physicsWorld.contactDelegate = self ????

     //setting up Physicsbody etc
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
}



import SpriteKit
import GameplayKit

class GameScene: SKScene, SKPhysicsContactDelegate {

    override func didMove(to view: SKView) {
        physicsWorld.contactDelegate = self
    }


    func didBegin(_ contact: SKPhysicsContact) {
        print("INSIDE MAIN: ",contact.bodyA.node?.name, contact.bodyB.node?.name)
    }


Or how do you manage large amount of contact logic?


Thanks for any help and sorry if the questions is weirdly formulated

Accepted Reply

You can write something like this:

@objc protocol ContactHandling {
    @objc optional func didBegin(_ contact: SKPhysicsContact, with node: SKNode?)
    @objc optional func didEnd(_ contact: SKPhysicsContact, with node: SKNode?)
}

class Ball: SKSpriteNode, ContactHandling {
    func didBegin(_ contact: SKPhysicsContact, with node: SKNode?) {
        print("INSIDE BALL(\(self.name ?? "name unknown")): ", node?.name ?? "name unknown")
    }
    
    //...
      
}


class GameScene: SKScene, SKPhysicsContactDelegate {
  
    //...  
  
    func didBegin(_ contact: SKPhysicsContact) {
        print("INSIDE MAIN: ",contact.bodyA.node?.name ?? "name unknownA", contact.bodyB.node?.name ?? "name unknownB")
        if let node = contact.bodyA.node as? ContactHandling {
            node.didBegin?(contact, with: contact.bodyB.node)
        }
        if let node = contact.bodyB.node as? ContactHandling {
            node.didBegin?(contact, with: contact.bodyA.node)
        }
    }

    //...
}

Not tested, so you may need some modification, but please try.

Replies

You can write something like this:

@objc protocol ContactHandling {
    @objc optional func didBegin(_ contact: SKPhysicsContact, with node: SKNode?)
    @objc optional func didEnd(_ contact: SKPhysicsContact, with node: SKNode?)
}

class Ball: SKSpriteNode, ContactHandling {
    func didBegin(_ contact: SKPhysicsContact, with node: SKNode?) {
        print("INSIDE BALL(\(self.name ?? "name unknown")): ", node?.name ?? "name unknown")
    }
    
    //...
      
}


class GameScene: SKScene, SKPhysicsContactDelegate {
  
    //...  
  
    func didBegin(_ contact: SKPhysicsContact) {
        print("INSIDE MAIN: ",contact.bodyA.node?.name ?? "name unknownA", contact.bodyB.node?.name ?? "name unknownB")
        if let node = contact.bodyA.node as? ContactHandling {
            node.didBegin?(contact, with: contact.bodyB.node)
        }
        if let node = contact.bodyB.node as? ContactHandling {
            node.didBegin?(contact, with: contact.bodyA.node)
        }
    }

    //...
}

Not tested, so you may need some modification, but please try.

Thank you this will take me a long way to understand SpriteKit