Alan Scarpa
Alan Scarpa

Reputation: 3570

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)

Upvotes: 0

Views: 818

Answers (2)

user13428
user13428

Reputation: 86

Actually, you're almost there. You just need to create a physics joint between the two chainsaw pieces:

// Where your joint will be .. you really should position your chainsaw
//     holder & longchainsaw first before you join them. 

let my_joint_point_in_scene_coordinates = chainsawHolder.position

let myJoint = SKPhysicsJointFixed.jointWithBodyA(
               chainsawHolder.physicsBody!,
               bodyB: longChainsaw.physicsBody!,
               anchor: my_joint_pt_in_scene_coords )
self.physicsWorld.addJoint(myJoint)

Also, if you want your long chainsaw to rotate within the chainsaw holder (like a wrist rotating from a forearm), instead of using a SKPhysicsJointFixed, use a SKPhysicsJointPin, and you can then rotate the longChainsaw node.

Upvotes: 0

CodeSmile
CodeSmile

Reputation: 64477

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.

Upvotes: 1

Related Questions