Sharukh
Sharukh

Reputation: 199

How do I detect contact between sprites declared in two different classes?

I have a GameScene class and Shapes Class. Shapes class consists of three different shapes. In my GameScene class, different sprites are loaded up and when the app lauches, a random shape comes to screen from Shapes class and comes in contact with one of the sprites. I have done several different methods to get the contact detection, but I think I'm missing something.

Here's the Shapes Class:

class Shapes: SKNode{

var cY = SKSpriteNode(imageNamed: "Shape1")
var sY = SKSpriteNode(imageNamed: "Shape2")
var pY = SKSpriteNode(imageNamed: "Shape3")


convenience init(pOffset: CGFloat) {
    self.init()
    positionOffset = pOffset

    self.addChild(cY)
    self.addChild(sY)
    self.addChild(pY)       
}

func updateDelta(delta: NSTimeInterval) {

  .....
}

GameScene Class:

var can1 : Shapes!

let shapesCategory: UInt32 = 1 << 0
let seaCategory: UInt32 = 1 << 1

class GameScene: SKScene, SKPhysicsContactDelegate {

    var sea = SKSpriteNode(imageNamed: "sea")
    sea.position = pos1

    physicsWorld.contactDelegate = self 

    sea.physicsBody = SKPhysicsBody(circleOfRadius: square.size.height / 2)
    sea.physicsBody!.affectedByGravity = false
    sea.physicsBody!.dynamic = false
    sea.physicsBody!.categoryBitMask = seaCategory
    sea.physicsBody!.collisionBitMask = shapesCategory
    sea.physicsBody!.contactTestBitMask = shapesCategory

    addChild(sea)

    // for now I'm just dealing with if shape 1 was to spawn
    can1 = Shapes(pOffset: size.width/4) // a shape spawns on this point
    can1.cY.physicsBody = SKPhysicsBody(circleOfRadius: self.size.height / 28)
    can1.cY.physicsBody!.dynamic = false
    can1.cY.physicsBody?.categoryBitMask = shapesCategory
    can1.cY.physicsBody?.collisionBitMask = seaCategory
    can1.cY.physicsBody?.contactTestBitMask = seaCategory

    addChild(can1)
}

func didBeginContact(contact: SKPhysicsContact) {
    if (contact.bodyA.categoryBitMask) == seaCategory || (contact.bodyB.
        categoryBitMask) == shapesCategory {

        print("contact")
    }

}

Would this also be the right way to approach it? Because everytime I refer to a specific shape from Shapes class, for instance, saying can1.shape1 makes the frames per second drop by drastically and makes it laggy.

Edit: fixed some errors in code line

Upvotes: 0

Views: 43

Answers (1)

Knight0fDragon
Knight0fDragon

Reputation: 16837

Your issue here is you are not creating the Physics Body correctly, in the original version of the code, you did not even assign the PhysicsBody to the shape for which you needed to for, you instead assigned it to the parent. In your new version, you assign it to the shape, but the value of the body does not match the sprite, so your collision will be off.

Instead, declare your body like this:

can1.cY.physicsBody = SKPhysicsBody(circleOfRadius: can1.cy.size.width / 2)

Your next issue is you have dynamics off, this essentially means that the physics should not happen at all, lets turn this on.

can1.cY.physicsBody!.dynamic = false

Finally, you have an issue with your didBeginContact code, the order is not preserved of who hits who, so you need to make sure that you are checking your fields correctly.

What you want is something like this:

func didBeginContact(contact: SKPhysicsContact) {
    let bodyA = (contact.bodyA.categoryBitMask <= contact.bodyB.categoryBitMask) ? contact.bodyA : contact.bodyB
    let bodyB = (contact.bodyA.categoryBitMask <= contact.bodyB.categoryBitMask) ? contact.bodyB : contact.bodyA

    if ((bodyA.categoryBitMask == shapesCategory ) && (bodyB.categoryBitMask == seaCategory )){

        print("contact")
    }

}

Upvotes: 1

Related Questions