Reputation: 3603
I just created a very basic scene in SpriteKit and first problem just appeared.
When two SKShapeNode get in contact, the player node is overlapping the ground node, I can't see why.
Here is my code and a screenshot:
import SpriteKit
class GameScene: SKScene, SKPhysicsContactDelegate {
var contentCreated = false
var player: SKShapeNode?
override func didMoveToView(view: SKView) {
if !contentCreated {
createSceneContents()
contentCreated = true
}
}
func createSceneContents() {
self.backgroundColor = SKColor(white: 1.0, alpha: 1.0)
self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
self.physicsWorld.gravity = CGVectorMake(0, -10)
self.physicsWorld.contactDelegate = self
let groundCategory: UInt32 = 0x1 << 0
let playerCategory: UInt32 = 0x1 << 0
let ground = SKShapeNode(rect: CGRectMake(0, 0, self.frame.width, 50))
ground.fillColor = UIColor.blueColor()
ground.lineWidth = 0
ground.position = CGPoint(x: 0, y: 0)
ground.physicsBody = SKPhysicsBody(rectangleOfSize: ground.frame.size)
ground.physicsBody?.dynamic = false
ground.physicsBody?.categoryBitMask = groundCategory
ground.physicsBody?.collisionBitMask = groundCategory
ground.physicsBody?.contactTestBitMask = groundCategory
self.addChild(ground)
player = SKShapeNode(rect: CGRectMake(0, 0, 30, 30))
player?.fillColor = UIColor.blackColor()
player?.lineWidth = 0
player?.position = CGPoint(x: 20, y: 400)
player?.physicsBody = SKPhysicsBody(rectangleOfSize: player!.frame.size)
player?.physicsBody?.mass = 1.0
player?.physicsBody?.categoryBitMask = playerCategory
player?.physicsBody?.collisionBitMask = playerCategory
player?.physicsBody?.contactTestBitMask = playerCategory
self.addChild(player!)
}
}
Thanks.
Upvotes: 0
Views: 863
Reputation: 6612
You might want to have a different bitmask for your ground
and player
:
let groundCategory: UInt32 = 0x1
let playerCategory: UInt32 = 0x1 << 1
Then you might also want to set the collision / contact bitmask differently :
ground.physicsBody?.categoryBitMask = groundCategory
ground.physicsBody?.collisionBitMask = playerCategory
ground.physicsBody?.contactTestBitMask = playerCategory
player?.physicsBody?.categoryBitMask = playerCategory
player?.physicsBody?.collisionBitMask = groundCategory
player?.physicsBody?.contactTestBitMask = groundCategory
Even so, you'll have something like you already have. However if you turn on the showPhysics
(as suggested by @Skoua) :
You can see that the physics body is attached to the bottom left anchor point.
Here is how to fix that :
func createSceneContents() {
self.backgroundColor = SKColor(white: 1.0, alpha: 1.0)
self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
self.physicsWorld.gravity = CGVectorMake(0, -10)
self.physicsWorld.contactDelegate = self
let groundCategory: UInt32 = 0x1
let playerCategory: UInt32 = 0x1 << 1
let ground = SKShapeNode(rectOfSize: CGSize(width: self.frame.width, height: 50)) // HERE
ground.fillColor = UIColor.blueColor()
ground.lineWidth = 0
ground.position = CGPoint(x: ground.frame.size.width/2, y: ground.frame.size.height/2) // HERE
ground.physicsBody = SKPhysicsBody(rectangleOfSize: ground.frame.size)
ground.physicsBody?.dynamic = false
ground.physicsBody?.categoryBitMask = groundCategory
ground.physicsBody?.collisionBitMask = playerCategory
ground.physicsBody?.contactTestBitMask = playerCategory
self.addChild(ground)
player = SKShapeNode(rectOfSize: CGSize(width: 30, height: 30)) // HERE
player?.fillColor = UIColor.blackColor()
player?.lineWidth = 0
player?.position = CGPoint(x: 20, y: 400)
player?.physicsBody = SKPhysicsBody(rectangleOfSize: player!.frame.size)
player?.physicsBody?.mass = 1.0
player?.physicsBody?.categoryBitMask = playerCategory
player?.physicsBody?.collisionBitMask = groundCategory
player?.physicsBody?.contactTestBitMask = groundCategory
self.addChild(player!)
}
Don't forget, when placing your node, that the default anchor point is the bottom left of the scene.
Upvotes: 2