As of now, I have an SKSpriteNode that detects collisions with my ball and increments my score by + 1 when they collide. Also in the collision is the code that detects if my ball hits a wall.
let scoreNode = SKSpriteNode()
scoreNode.size = CGSize(width: 750, height: 10)
scoreNode.position = CGPoint(x: self.frame.width / 2, y: self.frame.height / 2 + 100)
scoreNode.physicsBody = SKPhysicsBody(rectangleOfSize: scoreNode.size)
scoreNode.physicsBody?.affectedByGravity = false
scoreNode.physicsBody?.dynamic = true
scoreNode.physicsBody?.categoryBitMask = PhysicsCat.Score
scoreNode.physicsBody?.collisionBitMask = 0
scoreNode.physicsBody?.contactTestBitMask = PhysicsCat.Ball
scoreNode.color = SKColor.clearColor()
func didBeginContact(contact: SKPhysicsContact) {
let firstBody = contact.bodyA
let secondBody = contact.bodyB
if firstBody.categoryBitMask == PhysicsCat.Score && secondBody.categoryBitMask == PhysicsCat.Ball{
score += 1
scoreLbl.text = "\(score)"
firstBody.node?.removeFromParent()
}
else if firstBody.categoryBitMask == PhysicsCat.Ball && secondBody.categoryBitMask == PhysicsCat.Score {
score += 1
scoreLbl.text = "\(score)"
secondBody.node?.removeFromParent()
}
else if firstBody.categoryBitMask == PhysicsCat.Ball && secondBody.categoryBitMask == PhysicsCat.Wall || firstBody.categoryBitMask == PhysicsCat.Wall && secondBody.categoryBitMask == PhysicsCat.Ball{
enumerateChildNodesWithName("wallPair", usingBlock: ({
(node, error) in
node.speed = 0
self.removeAllActions()
}))
if died == false{
died = true
createBTN()
fallDie()
}
}
else if firstBody.categoryBitMask == PhysicsCat.Ball && secondBody.categoryBitMask == PhysicsCat.Wall {
enumerateChildNodesWithName("wallPair", usingBlock: ({
(node, error) in
node.speed = 0
self.removeAllActions()
}))
if died == false{
died = true
Ball.physicsBody?.velocity = CGVectorMake(0, 0)
createBTN()
}
}
}
I need a second collision detection that is completely separate from the above code^^. How do I make them separate? You can't have two didBeginContact's I don't think. I hope this isn't too vague or unclear. So obviously I need a second node, calling it colorNode. How would I detect a collision between my ball and colorNode (colorNode is about 200 pixels below my scoreNode, so they aren't in the same position), without messing up my code that detects collision between the ball and the wall?
You do not need a separate collision detection. What you need to do is to handle things in didBeginContact
. All those if-else checks with their || and && becomes quite unwieldy. (Exemplified by the fact that your last else
performs a check that's already been performed in the former else
).
The below code is an OK-ish attempt to make the if-logic more sensible. Creating a Bool
to handle the presence for each of the types we're interested in.
func didBeginContact(contact: SKPhysicsContact) {
let firstBody = contact.bodyA
let secondBody = contact.bodyB
let ballWasContacted = firstBody.categoryBitMask == PhysicsCat.Ball || secondBody.categoryBitMask == PhysicsCat.Ball
let wallWasContacted = firstBody.categoryBitMask == PhysicsCat.Wall || secondBody.categoryBitMask == PhysicsCat.Wall
let scoreWasContacted = firstBody.categoryBitMask == PhysicsCat.Score || secondBody.categoryBitMask == PhysicsCat.Score
Now that this logic has been defined in a fairly reasonable manner you come to the actual collision-checking where you really reap the rewards:
if ballWasContacted {
if scoreWasContacted {
score += 1
scoreLbl.text = "\(score)"
let scoreNode = firstBody.categoryBitMask == PhysicsCat.Score ? firstBody.node : secondBody.node
scoreNode!.removeFromParent()
} else if wallWasContacted {
enumerateChildNodesWithName("wallPair", usingBlock: ({
(node, error) in
node.speed = 0
self.removeAllActions()
}))
if died == false {
died = true
createBTN()
fallDie()
}
}
}
This should make it a lot easier to handle another ball vs. something collision. You just need a PhysicsCat.Color
and another Bool
. Then just hook another else if
onto the last.
else if colorWasContacted {
// Do stuff
}
Note: It's a good idea to also follow conventions. I'm thinking about your naming, do not abbreviate words. scoreLabel
not scoreLbl
PhysicsCategory
not PhysicsCat
*
*PhysicsCat? Is that Mr. Schroedinger's late pet?