Praveen Praveen -4 years ago 62
Swift Question

Sprites Colliding despite differing bitmasks

I have 5 different category bitmasks for my sprites:


  • redBullet (enemy shot)

  • greenBullet (playershot)

  • shipCategory (player Sprite)

  • enemyShipCategory (AI Sprite)

  • wallCategory (screen border)



I have set my bitmasks properly, but I am getting some collisions that should not happen. Both bullets will collide with each other and the wall instead of passing through. Why is this happening if those bitmasks aren't included in the collisionBitmap?

let shipCategory: UInt32 = 1
let wallCategory: UInt32 = 2
let greenBulletCategory: UInt32 = 3
let enemyShipCategory: UInt32 = 4
let redBulletCategory: UInt32 = 5

self.anchorPoint = CGPoint.init(x: 0.5, y: 0.5)
setUpHeaderUI()
self.physicsWorld.gravity = CGVector.zero
self.physicsWorld.contactDelegate = self
createBG()
addShip()
self.physicsBody = SKPhysicsBody.init(edgeLoopFrom: self.frame)
self.physicsBody?.collisionBitMask = shipCategory | enemyShipCategory
self.physicsBody?.categoryBitMask = wallCategory
self.physicsBody?.friction = 0

func enemyShoot(node: SKSpriteNode){
Bullet = SKSpriteNode.init(imageNamed: "red.svg.hi")
Bullet.zPosition = 1
Bullet.setScale(0.2)
Bullet.position = node.position
Bullet.physicsBody = SKPhysicsBody.init(rectangleOf: Bullet.size)
Bullet.physicsBody?.isDynamic = true
Bullet.physicsBody?.allowsRotation = true
Bullet.physicsBody?.linearDamping = 0
Bullet.physicsBody?.friction = 0
Bullet.physicsBody?.categoryBitMask = redBulletCategory
Bullet.physicsBody?.contactTestBitMask = shipCategory
Bullet.physicsBody?.velocity = CGVector.init(dx: ((node.physicsBody?.velocity.dx)!/100), dy: CGFloat.init(-750))
Bullet.name = "Bullet"
self.addChild(Bullet)
}

func playerShoot(){
changePower(change: 10)
if(power > 99 ){
consPowerTimer.invalidate()
changePower(change: 100 - power)
canFire = false
powerTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.powerCooldown), userInfo: nil, repeats: true)
}
else{
Bullet = SKSpriteNode.init(imageNamed: "green.svg.hi")
Bullet.zPosition = 1
Bullet.zRotation = CGFloat.init(3 * Double.pi/2)
Bullet.setScale(0.2)
Bullet.position = ship.position
Bullet.physicsBody = SKPhysicsBody.init(rectangleOf: Bullet.size)
Bullet.physicsBody?.isDynamic = true
Bullet.physicsBody?.allowsRotation = true
Bullet.physicsBody?.linearDamping = 0
Bullet.physicsBody?.friction = 0
Bullet.physicsBody?.categoryBitMask = greenBulletCategory
Bullet.physicsBody?.contactTestBitMask = enemyShipCategory
print(ship.physicsBody?.velocity.dx)
Bullet.physicsBody?.velocity = CGVector.init(dx: (ship.physicsBody?.velocity.dx)!, dy: CGFloat.init(750))
Bullet.name = "Bullet"
self.addChild(Bullet)
}

func addAttackShip(){
//30,40,40
let enemy = attackShip.init()
enemy.setScale(0.08)
enemy.zRotation = CGFloat(0)
enemy.physicsBody = SKPhysicsBody.init(rectangleOf: enemy.size)
enemy.physicsBody?.isDynamic = true
enemy.name = "enemy"
enemy.zPosition = 2
enemy.physicsBody?.mass = CGFloat.init(10)
enemy.physicsBody?.friction = 0
enemy.physicsBody?.categoryBitMask = enemyShipCategory
enemy.physicsBody?.collisionBitMask = enemyShipCategory | wallCategory
enemy.physicsBody?.contactTestBitMask = greenBulletCategory | shipCategory
enemy.position = CGPoint.init(x: 0, y: 155.504 - enemy.size.height / 2)
enemy.zRotation = CGFloat(2.4870942)
let healthindicator = SKSpriteNode.init(color: UIColor.green, size: CGSize.init(width: 150, height: 30))
healthindicator.name = "healthdisplay"
healthindicator.zPosition = 3
healthindicator.zRotation = -1 * CGFloat(2.4870942)
enemy.addChild(healthindicator)
addChild(enemy)
}

func addShip() {
ship = SKSpriteNode(imageNamed: "Spaceship")
ship.setScale(0.2)
ship.zRotation = CGFloat(0)
ship.physicsBody = SKPhysicsBody(rectangleOf: ship.size)
ship.physicsBody?.isDynamic = true
ship.name = "ship"
ship.position = CGPoint.init(x: 0, y: (-(self.frame.size.height/2)) + ship.size.height/2)
ship.zPosition = 2
ship.physicsBody?.mass = CGFloat.init(10)
ship.physicsBody?.friction = 0
ship.physicsBody?.categoryBitMask = shipCategory
ship.physicsBody?.collisionBitMask = wallCategory
ship.physicsBody?.contactTestBitMask = redBulletCategory | enemyShipCategory
self.addChild(ship)
if motionManager.isAccelerometerAvailable == true {
motionManager.startAccelerometerUpdates(to: OperationQueue.current!, withHandler:{
data, error in
if (data!.acceleration.y) < -0.05 {
self.velocity = -500
}

else if data!.acceleration.y > 0.05 {
self.velocity = 500
}
else{
self.velocity = 0
}

})

}
}

Answer Source

Your bullet's physicsBody does is not a collisionBitmask. As such it will assume the default mask of 0xFFFFFFFF and collide with everything. If you don't need it to collide with anything, assign it a collisionMask of 0.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download