Larisa
Larisa

Reputation: 791

The proper way of using didBeginContact in SpriteKit games - Swift

I have 3 sprites which can collide with each other and have contactTestBitMask and categoryBitMask set. I had two sprites which used didBeginContact method to see if they have collided and it worked fine, but now I am not sure how to set it to check contacts of multiple objects and run the function which is different depending on which two bodies collide.

My PhysicsCategory:

struct PhysicsCategory {
    static let None: UInt32 = 0
    static let All: UInt32 = UInt32.max
    static let Bird: UInt32 = 0b1
    static let Cloud: UInt32 = 0b10
    static let Desk: UInt32 = 0b100
    static let Star: UInt32 = 0b101
    static let StarSpecial: UInt32 = 0b110
}

The didBeginContact method in GameScene:

func didBeginContact(contact: SKPhysicsContact) {
    var BirdBody: SKPhysicsBody?
    var DeskBody: SKPhysicsBody?
    var SpecialStarBody: SKPhysicsBody?
    //var SpecialStarBody: SKPhysicsBody
    if contact.bodyA.categoryBitMask == PhysicsCategory.Bird {
        BirdBody = contact.bodyA
        DeskBody = contact.bodyB
    } else if contact.bodyA.categoryBitMask == PhysicsCategory.Desk {
        BirdBody = contact.bodyB
        DeskBody = contact.bodyA
    } else if contact.bodyA.categoryBitMask == PhysicsCategory.StarSpecial {
        SpecialStarBody = contact.bodyA
    }
    if (DeskBody != nil) {
        birdSprite.BirdDidCollideWithDesk(BirdBody?.node as! Bird, desk: DeskBody?.node as! Desk, scoreClass: scoreClass, scoreLabel: scoreLabel)
    }
}

What I want to do is check if the bird came in contact with a desk and in this case, it should run the function for the bird and the desk, otherwise I want to see whether bird came in contact with a SpecialStar, I haven't written a function for what to do in this case, but later on, I would call a different function for this case. I am also adding some additional sprites, so I would be grateful if anyone could explain how this should be done for code to be well written and not cause any errors.

Upvotes: 0

Views: 68

Answers (1)

Darvas
Darvas

Reputation: 974

You can check if bird contacted with desk

if ((contact.bodyA.categoryBitMask == PhysicsCategory.Bird && contact.bodyB.categoryBitMask == PhysicsCategory.Desk) ||
(contact.bodyA.categoryBitMask == PhysicsCategory.Desk && contact.bodyB.categoryBitMask == PhysicsCategory.Bird)) {

    print("Bird, desk")
    // Handle contact bird with desk
}

Bird contact with starSpecial

if ((contact.bodyA.categoryBitMask == PhysicsCategory.Bird && contact.bodyB.categoryBitMask == PhysicsCategory.StarSpecial) ||
(contact.bodyA.categoryBitMask == PhysicsCategory.Desk && contact.bodyB.categoryBitMask == PhysicsCategory.StarSpecial)) {

    print("Bird, StarSpecial")
    // Handle contact bird with StarSpecial
}

Just a note: Variables should start with a lowercase letter.

To keep code clear I recommend to create class file for every node.

import Foundation
import SpriteKit

class Monster: SKSpriteNode {

    init(world: SKNode) {

    super.init(texture: SKTexture(imageNamed: "MonsterImageName"), color: UIColor.clearColor(), size: CGSizeMake(world.frame.size.width / 18, world.frame.size.width / 36))
    position = CGPointMake(world.frame.size.width / 2, world.frame.size.height / 2)
    zPosition = 100

    // etc
    }

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

And add it like this

var monster = Monster.init(world)
world.addChild(monster)

Upvotes: 2

Related Questions