3
votes

I wanted to have a collision detection between the avatar and the obstacle, so whenever something collides, it should print "collision", but even that doesn't work, so the problem is, that it doesn't detect any collision. And if it would collide, it should differentiate between the player and the obstacle.

class GameScene: SKScene, SKPhysicsContactDelegate {
    let avatar = SKShapeNode(circleOfRadius: 20)

    let avatarCategory: UInt32 = 0*1 << 0
    let obstacleCategory: UInt32 = 0*1 << 1

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

        createAvatar()
        spawnObstacles()
    }

    func createAvatar() {
        avatar.name = "avatarNode"
        avatar.physicsBody = SKPhysicsBody()
        avatar.physicsBody?.categoryBitMask = avatarCategory
        avatar.physicsBody?.contactTestBitMask = avatarCategory
        avatar.physicsBody?.collisionBitMask = 0
        avatar.physicsBody?.usesPreciseCollisionDetection = true
        avatar.physicsBody?.affectedByGravity = false
        avatar.zPosition = 2

        addChild(avatar)
    }

    func createRandomObstacle() {
        let obstacle = SKShapeNode()

        obstacle.name = "obstacleNode"
        obstacle.physicsBody = SKPhysicsBody()
        obstacle.physicsBody?.categoryBitMask = obstacleCategory
        obstacle.physicsBody?.contactTestBitMask = obstacleCategory
        obstacle.physicsBody?.collisionBitMask = 0
        obstacle.physicsBody?.usesPreciseCollisionDetection = true
        obstacle.physicsBody?.affectedByGravity = false
        obstacle.zPosition = 2

        addChild(obstacle)
    }

    func didBegin(_ contact: SKPhysicsContact) {
        print("collision")
    }
1
That is a lot of code! consider reducing that to a minimal exampleHelder Sepulveda
yes, should be better nowGDog
That still a lot ... minimal to me is something about 40 lines of code...Helder Sepulveda
is it readable now?GDog

1 Answers

0
votes

To start with, both avatarCategory and obstacleCategory are 0, because : UInt32 = 0*1 << 1 = 0, so let’s fix that:

let avatarCategory: UInt32 = 1 << 0
let obstacleCategory: UInt32 = 1 << 1

Now contactTestBitMask represents the object(s) you want to be notified about contacts with, so you need to change that:

avatar.physicsBody?.contactTestBitMask = obstacleCategory

and

obstacle.physicsBody?.contactTestBitMask = avatarCategor

Try that for now 😀

Edit: my step-by-step guide for collisions and contacts: https://stackoverflow.com/a/51041474/1430420

And a guide to collision and contactTest bit masks: https://stackoverflow.com/a/40596890/1430420