Search code examples
iosswiftsprite-kitgame-physicsskphysicsbody

How do I maintain child SKNode velocities when moving the parent?


I'm working on a game in Swift with SpriteKit. I have a parent node with an SKPhysicsBody and several subnodes with their own physics bodies. All of the subnodes have some velocity relative to the parent node. How do I keep that relative velocity when giving the parent node a velocity? Here's pseudocode to show what I'm trying to do:

let parent:SKNode = SKNode()
let child:SKNode = SKNode()
parent.physicsBody = SKPhysicsBody()
child.physicsBody = SKPhysicsBody()
parent.addChild(child)

child.physicsBody!.velocity = CGVectorMake(dx: 5, dy: 5)
// child now has velocity
parent.physicsBody!.velocity = CGVectorMake(dx: 10, dy:10)
// parent has velocity, but child velocity is still (5,5)

How would I get the child velocity to be set such that it maintains a velocity relative to the parent? (e.g. the child's absolute velocity should become (15,15) once the parent is given a velocity of (10,10) so that it maintains (5,5) relative to the parent). I tried using SKPhysicsJoint but that seems to fix the node and not allow velocity. Any solutions? (I'm sure I'm overlooking something obvious, but I'm new to SpriteKit)
Thanks!


Solution

  • If you want the child's velocity to be relative to its parent, add the parent's velocity to the child's constant velocity in the update method. For example,

    override func update(currentTime: CFTimeInterval) {
        child.physicsBody?.velocity = CGVectorMake(parentNode.physicsBody!.velocity.dx + 5.0, parentNode.physicsBody!.velocity.dy + 5.0)
    }
    

    BTW, you shouldn't use parent as a variable name in Sprite Kit, since it's a property of SKNode.

    Update

    You can loop over all children of the parent node with the following.

    override func update(currentTime: CFTimeInterval) {
        for (i, child) in parentNode.children.enumerate() {
            child.physicsBody?.velocity = CGVectorMake(parentNode.physicsBody!.velocity.dx + velocity[i].dx, parentNode.physicsBody!.velocity.dy + velocity[i].dy)
        }
    }
    

    velocity is an array of CGVectors that contains the velocity of each child.