Search code examples
sprite-kitnodesgame-physicsskphysicsbody

How to create multiple node characters in sprite kit /SKphysics joint?


I am creating a game and for my character his legs and torso have separate animations so they are separate nodes with separate physics bodies. I am having a lot of trouble linking the torso and the legs together however, linking them is not the problem, keeping them linked is. While moving around sometimes the hero's torso slides off of the legs. Kind of funny but not practical lol. Here is my physics coding

enum BodyType:UInt32 {

case bullet1 = 2

case enemy1 =  4
case enemy2 =  16
case enemy3 =  32

case desertForegroundCase = 64

case tank11 =  128
case tank12 =  256
case tank13 =  512

case tank21 =  1024
case tank22 =  2048
case tank23 =  4056

case tank31 =  8112
case tank32 =  16224
case tank33 =  32448

case cliff1 =  64856
case cliff2 =  129212

case soldierT = 258424
case soldierL = 516848

static let ground: UInt32 = 1
}
     func CreateScene (){

    desertBackground.position = CGPoint(x: frame.size.width / 2, y: 
    frame.size.height / 2)
    desertBackground.size = CGSize (width: 1136, height: 640)
    desertBackground.zPosition = -5
    desertForegroundImage.position = CGPointMake(568, 100)
    desertForegroundImage.zPosition = -1
    let desertForeground = SKSpriteNode(texture: 
    desertForegroundTexture, size:CGSize(width: 1136, height: 200))
        desertForeground.position = CGPointMake(568, 100)
    let desertForegroundBody = SKPhysicsBody(texture: 
    desertForegroundTexture, size: CGSize(width: 1136, height: 200))
    desertForegroundBody.dynamic = false
    desertForegroundBody.affectedByGravity = false
    desertForegroundBody.allowsRotation = false
    desertForegroundBody.categoryBitMask = BodyType.ground
    desertForegroundBody.contactTestBitMask = BodyType.enemy1.rawValue 
    | BodyType.enemy2.rawValue | BodyType.enemy3.rawValue  | 
    BodyType.soldierL.rawValue | BodyType.soldierT.rawValue
    desertForeground.physicsBody = desertForegroundBody
    desertForeground.zPosition = -1

    self.addChild(desertForegroundImage)
    self.addChild(desertForeground)
    self.addChild(desert gully)

    }
   func CreateHero (){

    soldierLegs.position = CGPoint(x: 405 , y: 139)
    soldierLegs.zPosition = 1
    soldierLegs.anchorPoint.x = 0.6
    soldierLegs.anchorPoint.y = 0.7

    let soldierLegsBody:SKPhysicsBody = SKPhysicsBody(rectangleOfSize: 
    soldierLegs.size)
    soldierLegsBody.dynamic = true
    soldierLegsBody.affectedByGravity = true
    soldierLegsBody.allowsRotation = false
    //body.restitution = 0.4
    soldierLegsBody.categoryBitMask = BodyType.soldierL.rawValue
    soldierLegsBody.contactTestBitMask = BodyType.enemy1.rawValue | 
    BodyType.enemy2.rawValue | BodyType.enemy3.rawValue  | 
    BodyType.desertForegroundCase.rawValue
    soldierLegs.physicsBody = soldierLegsBody

    soldierTorso.position = soldierLegs.position
    soldierTorso.zPosition = 2
    soldierTorso.anchorPoint.x = 0.25
    soldierTorso.anchorPoint.y = 0.1

    let soldierTorsoBody:SKPhysicsBody = SKPhysicsBody(rectangleOfSize: 
    soldierTorso.size)
    soldierTorsoBody.dynamic = true
    soldierTorsoBody.affectedByGravity = true
    soldierTorsoBody.allowsRotation = false
    soldierTorsoBody.categoryBitMask = BodyType.soldierT.rawValue
    soldierTorsoBody.contactTestBitMask = BodyType.enemy1.rawValue | 
    BodyType.enemy2.rawValue | BodyType.enemy3.rawValue  | 
    BodyType.desertForegroundCase.rawValue
    soldierTorso.physicsBody = soldierTorsoBody
    let joint  = 
    SKPhysicsJointFixed.jointWithBodyA(soldierLegs.physicsBody!, bodyB: 
    soldierTorso.physicsBody!, anchor: soldierLegs.position)

    soldierLegsBody.collisionBitMask = BodyType.ground
    soldierTorsoBody.collisionBitMask = BodyType.ground

    self.addChild(soldierTorso)
    self.addChild(soldierLegs)
    self.physicsWorld.addJoint(joint)

enter image description here }

That's about how far he will slide off. Is there a way to just code one physics body with 2 separate nodes? or am i just missing a little code? Any help is help, thank you.


Solution

  • I figured it out, after declaring the physics joint

    let joint = 
    SKPhysicsJointFixed.jointWithBodyA(soldierLegs.physicsBody!, 
    bodyB:soldierTorso.physicsBody!, anchor: soldierLegs.position)
    

    declare the second node of the joint's dynamic value as false by

        joint.bodyB.dynamic = false
    

    then reposition the node using the update function

     override func update(currentTime: CFTimeInterval) {
    
       soldierTorso.position = soldierLegs.position
    
    }
    

    Positioning the extra node 60 times per second should make sure the node does not move, or for a higher frame rate or a smoother run im sure positioning it 5 - 20 times per second would do fine however positioning the torso 60 times per second did not reduce any frame rate speed for me