Floyd Resler
Floyd Resler

Reputation: 1786

How To Setup Multiple Physics Bodies in SpriteKit

I need to have two physics bodies on my playerSprite. I need one body to be a smaller contact area and to only detect collisions on certain bodies. My code is inside my PlayerNode class is:

let walkingBitMask = PhysicsCategory.Door | PhysicsCategory.Wall | PhysicsCategory.SlideTerminator | PhysicsCategory.Shootable
let contactBitMask = PhysicsCategory.Monster | PhysicsCategory.Door | PhysicsCategory.Item | PhysicsCategory.Slide | PhysicsCategory.Teleport
let mainBody = SKPhysicsBody(rectangleOf: CGSize(width: 40, height: 50))
mainBody.collisionBitMask = walkingBitMask
mainBody.contactTestBitMask = contactBitMask
    
let pitBody = SKPhysicsBody(rectangleOf: CGSize(width: 8, height: 8))
pitBody.contactTestBitMask = PhysicsCategory.Pit
pitBody.collisionBitMask = 0
    
self.physicsBody = SKPhysicsBody(bodies: [mainBody,pitBody])
self.physicsBody?.affectedByGravity = false
self.physicsBody?.categoryBitMask = PhysicsCategory.Player
self.name = "player"
self.physicsBody?.allowsRotation = false

The Pit category is all I want to interact with the pitBody. My code in setting up the Pit sprites is:

sprite.physicsBody=SKPhysicsBody(rectangleOf: CGSize(width: 8, height: 8))
sprite.physicsBody?.affectedByGravity = false
sprite.physicsBody?.isDynamic = false
sprite.name = "pit"
sprite.physicsBody?.allowsRotation = false
sprite.physicsBody?.categoryBitMask = PhysicsCategory.Pit
sprite.physicsBody?.collisionBitMask = 0

The problem I'm running into is that the player sprite stops moving when it encounters a pit sprite. Everything else works fine.

Upvotes: 0

Views: 185

Answers (1)

clns
clns

Reputation: 2304

When you create a physics body using SKPhysicsBody.init(bodies:), the properties on the children are ignored. Only the shapes of the child bodies are used, according to the docs.

So the test bit masks specified on mainBody and pitBody are ignored, and the compound body of the player that is part of the simulation only specifies the categoryBitMask:

self.physicsBody?.categoryBitMask = PhysicsCategory.Player

This means it will collide with other bodies, since it's collisionBitMask default value is 0xFFFFFFFF (all bits set).

Configure the collisionBitMask and contactTestBitMask on the player body.
If you need to use separate collisions, consider using a SKPhysicsJointFixed to fuse the two physics bodies together.

Upvotes: 1

Related Questions