Skoua
Skoua

Reputation: 3603

SpriteKit: SKShapeNodes overlapping

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!)
    }
}

enter image description here

Thanks.

Upvotes: 0

Views: 863

Answers (1)

lchamp
lchamp

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) :

physics

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!)
}

nowOkay

Don't forget, when placing your node, that the default anchor point is the bottom left of the scene.

Upvotes: 2

Related Questions