Stefan Kendall
Stefan Kendall

Reputation: 67802

SKPhysicsBody scale with parent scaling

I have a node, A, in a parent node, B.

I'm using setScale on node B to give the illusion of zooming, but when I do that, node A and all of its siblings do not have the expected physics bodies.

Even though A appears smaller and smaller, its physics body stays the same size. This leads to wacky behavior.

How can I "zoom out" and still have sensible physics?

Upvotes: 2

Views: 529

Answers (3)

0x141E
0x141E

Reputation: 12753

A simple example that shows that a physics body scales/behaves appropriately when its parent node is scaled. Tap to add sprites to the scene.

class GameScene: SKScene {

    var toggle = false
    var node = SKNode()

    override func didMoveToView(view: SKView) {
        self.physicsBody = SKPhysicsBody(edgeLoopFromRect: view.frame)
        scaleMode = .ResizeFill
        view.showsPhysics = true
        addChild(node)
        let shrink = SKAction.scaleBy(0.25, duration: 5)
        let grow = SKAction.scaleBy(4.0, duration: 5)
        let action = SKAction.sequence([shrink,grow])
        node.runAction(SKAction.repeatActionForever(action))
    }

    override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
        /* Called when a touch begins */

        for touch in (touches as! Set<UITouch>) {
            let location = touch.locationInNode(node)
            let sprite = SKSpriteNode(imageNamed:"Spaceship")

            if (toggle) {
                sprite.physicsBody = SKPhysicsBody(circleOfRadius: sprite.size.width/2.0)
            }
            else {
                sprite.physicsBody = SKPhysicsBody(rectangleOfSize: sprite.size)
            }

            sprite.xScale = 0.125
            sprite.yScale = 0.125
            sprite.position = location

            node.addChild(sprite)

            toggle = !toggle
        }
    }
}

Upvotes: 1

ABakerSmith
ABakerSmith

Reputation: 22939

The SKCameraNode (added in iOS9) sounds perfect for your scenario. As opposed changing the scale of every node in the scene, you would change the scale of only the camera node.

Firstly, you need to add an SKCameraNode to your scene's hierarchy (this could all be done in the Sprite Kit editor too).

override func didMoveToView(view: SKView) {
    super.didMoveToView(view)

    let camera = SKCameraNode()
    camera.position = CGPoint(x: size.width / 2, y: size.height / 2)
    self.addChild(camera)
    self.camera = camera
}

Secondly, since SKCameraNode is a node you can apply SKActions to it. For a zoom out effect you could do:

guard let camera = camera else { return }
let scale = SKAction.scaleBy(2, duration: 5)
camera.runAction(scale)

For more information have a look at the WWDC 2015 talk: What's New In Sprite Kit.

Upvotes: 2

sangony
sangony

Reputation: 11696

SKPhysicsBody cannot be scaled. As a hack you could destroy the current physics body and add a smaller one as you scale up or down but unfortunately this is not a very efficient solution.

Upvotes: 3

Related Questions