Reputation: 91
What I have now: Most of my current Sprite Node collisions work the way they should, except for the boxNode coming in contact with the floorNode. I have 3 sprite nodes: a floorNode, playerNode, and boxNode. The playerNode bounces in the air when the user taps the screen, and the boxNode(s)spawn from the ceiling and fall until coming in contact with the floorNode.
The Problem: The collision that Im having trouble with is when the boxNode collides with the floorNode. The game currently ends when the boxNode comes in contact with the floorNode, when all that should happen is the boxNode disappears when colliding with the floorNode.
playerNode collides with floorNode = game over
boxNode collides with playerNode = game over
boxNode collides with floorNode = (The game ends when this collision occurs) Shouldn't cause the game to end.
This is my current code:
import UIKit
import SpriteKit
import SceneKit
import Foundation
import CoreData
import GameplayKitstruct
ColliderType {
static let blueBallCategory: UInt32 = 0x1 << 0
static let floorNode: UInt32 = 0x1 << 1
static let firstBody: UInt32 = 0x1 << 2
static let secondBody: UInt32 = 0x1 << 3
static let boxNodeCategory: UInt32 = 0x1 << 4
}
class GameScene: SKScene, SKPhysicsContactDelegate {
floorNode.contactTestBitMask = 0
floorNode.categoryBitMask = ColliderType.floorNodeCategory
floorNode.collisionBitMask = ColliderType.playerNodeCategory | ColliderType.boxNodeCategory
self.physicsBody = floorNode
self.physicsBody?.friction = 0
playerNode.physicsBody?.categoryBitMask = ColliderType.playerNodeCategory
playerNode.physicsBody?.contactTestBitMask = 0
playerNode.physicsBody?.collisionBitMask = ColliderType.floorNodeCategory
boxNode.physicsBody?.categoryBitMask = ColliderType.boxNodeCategory
boxNode.physicsBody?.contactTestBitMask = ColliderType.playerNodeCategory | ColliderType.floorNodeCategory
boxNode.physicsBody?.collisionBitMask = 0
func didBegin(_ contact:SKPhysicsContact) {
let firstBody = contact.bodyA
let secondBody = contact.bodyB
if firstBody.categoryBitMask == ColliderType.playerNodeCategory || secondBody.categoryBitMask == ColliderType.boxNodeCategory{
self.boxNode.removeFromParent()
gameOver = true
self.speed = 0
timer.invalidate()
}else if firstBody.categoryBitMask == ColliderType.floorNodeCategory || secondBody.categoryBitMask == ColliderType.floorNodeCategory {
gameOver = true
self.speed = 0
timer.invalidate()
}else if firstBody.categoryBitMask == ColliderType.boxNodeCategory || secondBody.categoryBitMask == ColliderType.floorNodeCategory{
self.boxNode.removeFromParent()
}else if contact.bodyA.categoryBitMask == ColliderType.boxNodeCategory{
contact.bodyA.node!.removeFromParent()
}else if contact.bodyB.categoryBitMask == ColliderType.boxNodeCategory{
contact.bodyB.node!.removeFromParent()
gameOver = true
self.speed = 0
timer.invalidate()
}
}
}
Upvotes: 0
Views: 290
Reputation: 4526
The problem seems that you have not accounted properly for the fact that the method didBegin(contact:) bodyA and bodyB could be in either order. For example if physics body X collides with physics body Y, the method didBegun(contact:) could be called with bodyA=X and bodyB=Y or bodyA=Y and bodyB=X. Your code needs to account for that and currently it does not.
Specifically the case where bodyA is the floor and bodyB is the box: this will fail all except your last condition - which ends the game.
Upvotes: 0