0
votes

Example:

This wall is preset at the load,

var preWall = SKSpriteNode(texture: preWallTexture, size: CGSize(width: width, height: height))

preWall.position = CGPoint(x: x, y: y)

preWall.physicsBody = SKPhysicsBody(edgeLoopFromRect: CGRect(x: x, y: y, width: width, height: height))
preWall.physicsBody?.affectedByGravity = false
preWall.physicsBody?.dynamic = false
preWall.physicsBody?.categoryBitMask = BLOCK

preWall.name = "preWall"

self.addChild(preWall)

And these "sand" particles are created after the user touches a spawner (red-block on the screen),

var img = "BlockRed.png"
let sand = SKSpriteNode (imageNamed: img)
var randLoc = arc4random_uniform(26)
sand.position = CGPointMake(location.x - CGFloat(10) + CGFloat(randLoc), location.y)
sand.name = "redSand"
sand.zPosition = 0
self.addChild(sand)

//gravity
sand.physicsBody?.affectedByGravity = true

//contact
sand.physicsBody!.categoryBitMask = PARTICLE
sand.physicsBody?.collisionBitMask = BLOCK | PARTICLE
sand.physicsBody?.contactTestBitMask = BLOCK | PARTICLE
sand.physicsBody = SKPhysicsBody(circleOfRadius: sand.frame.width - 3)

However, when they come into contact, the particles just fall through the walls. Why is this happening, and how do I fix it?

Note:

// Constants
let NOTHING: UInt32    = 0x1 << 0
let PARTICLE: UInt32   = 0x1 << 1
let BLOCK: UInt32      = 0x1 << 2
2

2 Answers

1
votes

You are initialising the physics body of the sand particle after you set the bit masks. Try changing the order of the lines.

sand.physicsBody = SKPhysicsBody(circleOfRadius: sand.frame.width - 3)
sand.physicsBody?.categoryBitMask = PARTICLE
sand.physicsBody?.collisionBitMask = BLOCK | PARTICLE
sand.physicsBody?.contactTestBitMask = BLOCK | PARTICLE
0
votes

The physics body of the preset node was not a volume-based body, and therefore was not colliding with the sand particles. I switched from:

preWall.physicsBody = SKPhysicsBody(edgeLoopFromRect: CGRect(x: x, y: y, width: width, height: height))

to

preWall.physicsBody = SKPhysicsBody(rectangleOfSize: preWall.frame.size)