I'm making a small game, like flappy bird. I have no idea why objects not "see" ourselves. I'm adding a Wall, Ground, and a Ghost, and what is pretty strange, Ghost detect a Ground, and vice versa, but Wall is still invisible. Why?
a ghost should stop on vertical rectangle (Wall), not fall on the ground.
struct PhysicsCatagory{
static let Ghost : UInt32 = 0x1 << 1
static let Wall : UInt32 = 0x1 << 2
static let Ground : UInt32 = 0x1 << 3
}
class GameScene: SKScene{
var Ground = SKSpriteNode()
var Ghost = SKSpriteNode()
var Wall = SKSpriteNode()
override func didMove(to view: SKView) {
/*******adding ground***/
Ground = SKSpriteNode(imageNamed: "Ground")
Ground.setScale(0.7)
Ground.position = CGPoint(x: self.frame.midX, y: self.frame.minY)
Ground.physicsBody = SKPhysicsBody(rectangleOf: Ground.size)
Ground.physicsBody?.categoryBitMask = PhysicsCatagory.Ground
Ground.physicsBody?.collisionBitMask = PhysicsCatagory.Ghost
Ground.physicsBody?.contactTestBitMask = PhysicsCatagory.Ghost
Ground.physicsBody?.affectedByGravity = false
Ground.physicsBody?.isDynamic = false
Ground.zPosition = 3
self.addChild(Ground)
/*******adding wall (not working)****/
Wall = SKSpriteNode(imageNamed: "Wall")
Wall.setScale(0.7)
Wall.position = CGPoint(x: self.frame.midX, y: self.frame.midY + 100)
Wall.physicsBody? = SKPhysicsBody(rectangleOf: Wall.size)
Wall.physicsBody?.categoryBitMask = PhysicsCatagory.Wall
Wall.physicsBody?.collisionBitMask = PhysicsCatagory.Ghost
Wall.physicsBody?.contactTestBitMask = PhysicsCatagory.Ghost
Wall.physicsBody?.affectedByGravity = false
Wall.physicsBody?.isDynamic = false
Wall.zPosition = 1
self.addChild(Wall)
/*******adding ghost***/
Ghost = SKSpriteNode(imageNamed: "Ghost")
Ghost.size = CGSize(width: 90, height: 100)
Ghost.position = CGPoint(x: self.frame.midX, y: self.frame.maxY)
Ghost.physicsBody = SKPhysicsBody(circleOfRadius: 50)
Ghost.physicsBody?.categoryBitMask = PhysicsCatagory.Ghost
Ghost.physicsBody?.collisionBitMask = PhysicsCatagory.Wall | PhysicsCatagory.Ground
Ghost.physicsBody?.contactTestBitMask = PhysicsCatagory.Wall | PhysicsCatagory.Ground
Ghost.physicsBody?.affectedByGravity = true
Ghost.physicsBody?.isDynamic = true
Ghost.zPosition = 2
self.addChild(Ghost)
}
Take a look at this:
Wall.physicsBody? = SKPhysicsBody(rectangleOf: Wall.size)
Notice the question mark here. It is used to specify optional chaining:
Optional chaining is a process for querying and calling properties, methods, and subscripts on an optional that might currently be nil. If the optional contains a value, the property, method, or subscript call succeeds; if the optional is nil, the property, method, or subscript call returns nil.
Now, assignment is a part of an optional chaining too. So if a property is nil, the assignment will fail.
In your case, a physicsBody property is nil, so none of the code on the right hand side of the = operator is evaluated.
To make this work, do this:
Wall.physicsBody = SKPhysicsBody(rectangleOf: Wall.size)
Something unrelated to this, but a good thing to keep in mind:
If you are interested in contact detection between two bodies, at least one has to be dynamic. I point this out because your Wall and Ground objects are static, meaning that no contacts will be detected between them no matter how you set the contact masks up.
Oh, and yeah, use camelCase notation for naming classes, properties, and so on.