P.Dane
P.Dane

Reputation: 91

Swift 3 Sprite Node Contact / Collision not behaving properly

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

Answers (1)

Ali Beadle
Ali Beadle

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

Related Questions