2

So I have my "Floor.swift" class below which is basically a bunch of walls. I have objects coming from the top of the screen and once the Floor and SKSpriteNodes collide, I'd like the SKSpriteNode to be removed. Below is my Floor class.

import Foundation
import SpriteKit

    class Floor: SKNode {
        override init() {
            super.init()

            let leftWall = SKSpriteNode(color: UIColor.brown, size: CGSize(width: 5, height: 50))
            leftWall.position = CGPoint(x: 0, y: 50)
            leftWall.physicsBody = SKPhysicsBody(rectangleOf: leftWall.size)
            leftWall.physicsBody!.isDynamic = false
            self.addChild(leftWall)

            let rightWall = SKSpriteNode(color: UIColor.brown, size: CGSize(width: 5, height: 50))
            rightWall.position = CGPoint(x: 375, y: 50)
            rightWall.physicsBody = SKPhysicsBody(rectangleOf: rightWall.size)
            rightWall.physicsBody!.isDynamic = false
            self.addChild(rightWall)

            let bottomWall = SKSpriteNode(color: UIColor.brown, size: CGSize(width: 500, height: 10))
            bottomWall.position = CGPoint(x: 150, y: -5)
            bottomWall.physicsBody = SKPhysicsBody(rectangleOf: bottomWall.size)
            bottomWall.physicsBody!.isDynamic = false
            self.addChild(bottomWall)

            // Set the bit mask properties
            self.physicsBody?.categoryBitMask = floorCategory
            self.physicsBody?.contactTestBitMask = objectCategory | pointCategory | lifeCategory
            self.physicsBody?.collisionBitMask = dodgeCategory
        }

        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemted")
        }
    } 

Then in my GameScene class under "func didBegin(_ contact: SKPhysicsContact)" I wrote:

 if (contact.bodyA.categoryBitMask == floorCategory) && (contact.bodyB.contactTestBitMask == objectCategory | pointCategory | lifeCategory) {
              contact.bodyB.node!.removeFromParent()
              print("COLLISION")
}

But for some reason I'm not getting any detection what's so ever. I made my "Floor" class be a "contactTestBitMask" on each class of my objectCategory, pointCategory, lifeCategory. What am I doing wrong!? My other collisions are detected but not this one.

Dewan
  • 429
  • 3
  • 16

1 Answers1

3

Your leftWall, rightWall and bottomWall have the default contactTest and collision bit masks, so will collide with everything and generate contacts with nothing. Except they all have their isDynamic property set to false, so they can’t collide with or contact anything (although other things can collide and contact them if those other things have isDynamic set to true).

But this is probably what you want (Floors and walls are usually not dynamic). I suspect the real problem is that objects of Floor class won’t have a physics body, unless you initialise it somewhere else. You have these lines:

self.physicsBody?.categoryBitMask = ... self.physicsBody?.contactTestBitMask = ... self.physicsBody?.collisionBitMask = ...

but you haven't actually created self.physicsBody. Your code would crash except you’ve used optional chaining (self,phyicsBody?) and so Swift gets to the ‘?’ and says “Oh - it’s optional and doesn’t exist. I’ll just stop here then”

At the very least, try creating a physics body for your Floor object using the physics bodies of the 3 wall objects:

Self.physicsBody = SKPhysicsBody(Bodies: [leftWall.physicsBody, rightWall.PhysicsBoidy, bottomWall.physicsBody])

(SKPhysicsBody has an initialiser that takes an array of physics bodies to create a new physics body).

Steve Ives
  • 7,894
  • 3
  • 24
  • 55
  • I tried doing "let ourUnionOfBodies = SKPhysicsBody(bodies: [leftWall.physicsBody!, rightWall.physicsBody!, bottomWall.physicsBody!])" and following that I wrote on the next line "ourUnionOfBodies.isDynamic = false" but it still doesn't work? I don't see no collision detection they just fall right through – Dewan Dec 22 '17 at 23:42
  • @Dewan Hi Dewan - sorry for ther late reply but I was travelling. So you’ve created an `ourUnionOfBodies` physics body, and you’ve set that physics body to be non-dynamic, but have you set this as the Floor object’s physics body anywhere? You’ll still need to do a `self.physicsBody = ` before doing any of the `self.physicsBody?...` stuff. Any reason why you’ve created a separate property to hold the physics body rather than just do `self.physicsBody = SkyphysicsBody(bodies...`)?` – Steve Ives Dec 24 '17 at 12:20
  • I tried that but it didn’t really make a difference, I did not see collision detection. They kept falling through my Floor – Dewan Dec 24 '17 at 20:02
  • I think you need to show more code. Specifically the latest version of your Floor class with the `self.physicsBody =` assignment and how you create your object of 'Floor' class and set its contactTest and collision bit masks. – Steve Ives Dec 27 '17 at 10:34