Search code examples
iosswiftsprite-kitgame-physicsskphysicsbody

How to add physicsBody as child to SKSpriteNode?


I've created a container SKSpriteNode, called chainsawHolder, which has a child SKSpriteNode called longChainsaw. I want to apply an impulse to the chainsawHolder so that as it moves, it's child node moves with it. I've tried several things, but I'm unable to achieve this. It seems that only my container SKSpriteNode can only have a physicsSize. But it's childNode can't have a size - and if it does, it will not move along with the container node.

I need the child node to be a physics node because when it collides with my hero, it needs to call a function.

How can I get my child node to move along with the container node when the impulse is applied?

Here's the code:

let chainsawHolderWidth = size.width
    let chainsawHolderHeight = size.height
    chainsawHolder.size = CGSize(width: chainsawHolderWidth, height: chainsawHolderHeight)
    chainsawHolder.anchorPoint = CGPoint(x: 0, y: 0)
    chainsawHolder.position = CGPoint(x: 0, y: 0)


    chainsawHolder.physicsBody = SKPhysicsBody(rectangleOfSize: chainsawHolder.size)
    chainsawHolder.physicsBody?.dynamic = true
    chainsawHolder.physicsBody?.categoryBitMask = bgCategory
    chainsawHolder.physicsBody?.contactTestBitMask = boCategory
    chainsawHolder.physicsBody?.collisionBitMask = noneCategory



    //LONG CHAINSAW
    let longChainsawWidth = size.width/3
    let longChainsawHeight = size.height*0.20

    longChainsaw.size = CGSize(width: longChainsawWidth, height: longChainsawHeight)
    let textures = [SKTexture(imageNamed: "chainsaw1"), SKTexture(imageNamed: "chainsaw2")]
    let animation = SKAction.animateWithTextures(textures, timePerFrame: 0.1)
    let runSawAnimation = SKAction.repeatActionForever(animation)
    longChainsaw.runAction(runSawAnimation)



    let longChainsawPhysicsSize = CGSizeMake(longChainsawWidth - longChainsawWidth/14, longChainsawHeight - longChainsawHeight/12)
    longChainsaw.physicsBody = SKPhysicsBody(rectangleOfSize: longChainsawPhysicsSize)


    longChainsaw.position = CGPoint(x: size.width*0.5, y: size.height*0.5)

    longChainsaw.physicsBody?.dynamic = true
    longChainsaw.physicsBody?.categoryBitMask = chainsawCategory
    longChainsaw.physicsBody?.contactTestBitMask = boCategory
    longChainsaw.physicsBody?.collisionBitMask = noneCategory


    chainsawHolder.addChild(longChainsaw)
    self.addChild(chainsawHolder)

Solution

  • The physics engine has no concept of a parent-child relationship.

    What you can do is connect the two bodies with a joint. However this means there will always be a certain amount of flexibility when applying forces to the bodies.

    The alternative is to apply forces to the holder, then in the scene's update method set the position of the long chainsaw to the holder position plus an offset.