fuzzygoat fuzzygoat - 2 months ago 10
Swift Question

How to copy SKSpriteNode with SKPhysicsBody?

I am curious about a situation that I came across today when trying to unarchive and copy a

SKSpriteNode
from one
SKScene
to another. In the output from the playground below you can see that both
linearDamping
and
angularDamping
or not being maintained after the copy (they seem to be dropping back to default values)

// PLAYGROUND_SW1.2 - SKSpriteNode Copy
import UIKit
import SpriteKit

// ORIGINAL
let spriteNode = SKSpriteNode()
spriteNode.name = "HAPPY_NODE"
let size = CGSize(width: 55.0, height: 150.0)
let physics = SKPhysicsBody(rectangleOfSize: size)
physics.linearDamping = 0.123
physics.angularDamping = 0.456
spriteNode.physicsBody = physics

// COPY
let spriteCopy = spriteNode.copy() as! SKSpriteNode

// ORIGINAL
spriteNode.name
spriteNode.physicsBody?.linearDamping
spriteNode.physicsBody?.angularDamping
spriteNode.physicsBody?.area

// COPY
spriteCopy.name
spriteCopy.physicsBody?.linearDamping
spriteCopy.physicsBody?.angularDamping
spriteCopy.physicsBody?.area


PLAYGROUND OUTPUT
enter image description here

I am not sure that I am copying this correctly, both
SKSpriteNode
and
SKPhysicsBody
conform to
NSCopying
If you look at the output above the
area
property is maintained after the copy and to my knowledge this is based on the
size
specified when the
SKPhysicsBody
was created.

Can anyone cast some light on this and maybe provide me with a pointer as to how I should be deep copying an
SKSpriteNode
?

Answer

I take one way to resolve your problem, probably is not the best way, but

   //COPY
   let spriteCopy = spriteNode.copy() as SKSpriteNode
   let physicsCopy:SKPhysicsBody = spriteNode.physicsBody!;

   ...
   //COPY PHYSICS BODY HARD MODE
   spriteCopy.physicsBody = physicsCopy;

To fix this problem, I created one extension.

extension SKSpriteNode
{
   func copyWithPhysicsBody()->SKSpriteNode
   {
      let node = self.copy() as SKSpriteNode;
      node.physicsBody = self.physicsBody;
      return node;
   }
}

With this extension you can do it

// COPY
let spriteCopy = spriteNode.copyWithPhysicsBody();

// ORIGINAL
spriteNode.name
spriteNode.physicsBody?.linearDamping
spriteNode.physicsBody?.angularDamping
spriteNode.physicsBody?.area


// COPY
spriteCopy.name
spriteCopy.physicsBody?.linearDamping
spriteCopy.physicsBody?.angularDamping
spriteCopy.physicsBody?.area

enter image description here

Comments