Will Von Ullrich February 2016

Node with Two Physics Bodies

I know that this question has been "asked" here but it was not helpful, nor did it cover what I am asking.

That being said, I want to know how to achieve the following:

  • I need a node that has 2 physics bodies: 1) a smaller body (200x200) that represents the node's frame, and 2) a larger body (500x500) that represents an outer perimeter of an area that will act as a "detection" boundary. The outer body will not physically impact colliding objects, it just needs to register that an object has encountered that boundary line. Below is a simple idea of what I am describing:

enter image description here

My initial approach was to use SKPhysicsBody bodyWithBodies:<NSArray> but that would have just created the overlap body as the smaller rect.

So I figured I would have to create an SKSpriteNode for the smaller body (the black square), and another SKSpriteNode for the larger body (the blue square), and add it as a child to the smaller square (or vice versa).

My problem is that I can't seem to get the outer boundary to allow another object to pass through while registering that interaction. The closest I have come is getting a movable node to hit the boundary, then continually get pushed back and forth along the line of the 500x500 boundary as long as I attempt to pass through the boundary. I have been able to make the moving node UNABLE to pass through the 500x500, but this is quite the opposite of what I need.

Here is the code that I am using, perhaps someone can see something I am doing wrong:


// Detection body - 500x500
SKSpriteNode *dbody = [SKSpriteNode spriteNodeWithImageNamed:@"object500"];
dbody.position = CGPointMake(500, 100);


hamobi February 2016

this is working for me. sorry i didnt write it on obj c. just a lot faster for me in swift

import SpriteKit

let CategoryOuter:UInt32     = 1 << 0
let CategoryInner:UInt32     = 1 << 1
let CategoryTester:UInt32    = 1 << 2

class GameScene: SKScene, SKPhysicsContactDelegate {

    let outerSprite = SKSpriteNode(color: SKColor.redColor(), size: CGSizeMake(100, 100))
    let innerSprite = SKSpriteNode(color: SKColor.blueColor(), size: CGSizeMake(40, 40))
    let tester = SKSpriteNode(color: SKColor.greenColor(), size: CGSizeMake(10, 10))

    override init(size: CGSize) {
        super.init(size: size)
        physicsWorld.contactDelegate = self
        physicsWorld.gravity = CGVectorMake(0, 0)

        outerSprite.position = CGPointMake(size.width/2, size.height/2)
        outerSprite.physicsBody = SKPhysicsBody(rectangleOfSize: outerSprite.size)
        outerSprite.physicsBody!.dynamic = false
        outerSprite.physicsBody!.categoryBitMask = CategoryOuter
        outerSprite.physicsBody!.collisionBitMask = 0
        outerSprite.physicsBody!.contactTestBitMask = CategoryTester

        innerSprite.physicsBody = SKPhysicsBody(rectangleOfSize: innerSprite.size)
        innerSprite.physicsBody!.dynamic = false
        innerSprite.physicsBody!.categoryBitMask = CategoryInner
        innerSprite.physicsBody!.collisionBitMask = CategoryTester
        innerSprite.physicsBody!.contactTestBitMask = CategoryTester


        tester.physicsBody = SKPhysicsBody(rectangleOfSize: tester.size)
        tester.physicsBody!.categoryBitMask = CategoryTester
        tester.physicsBody!.collisionBitMask = CategoryInner

    func didBeginContact(contact: SKPhysicsContact) {
        let collision:UInt32 = (contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask)

        if collision == (CategoryOuter | CategoryTester) {

Post Status

Asked in February 2016
Viewed 2,674 times
Voted 12
Answered 1 times


Leave an answer