SKPhysicsBody 比例与父比例

SKPhysicsBody scale with parent scaling

我在父节点 B 中有一个节点 A。

我在节点 B 上使用 setScale 来产生缩放的错觉,但是当我这样做时,节点 A 及其所有兄弟姐妹都没有预期的物理体。

尽管A看起来越来越小,但它的物理体却保持不变。这会导致古怪的行为。

我怎样才能 "zoom out" 并且仍然有理智的物理知识?

SKPhysicsBody 无法缩放。作为 hack,您可以破坏当前的物理体,并在放大或缩小时添加一个较小的物理体,但不幸的是,这不是一个非常有效的解决方案。

SKCameraNode(在 iOS9 中添加)听起来非常适合您的场景。与更改场景中每个节点的比例相反,您可以仅更改相机节点的比例。

首先,您需要将 SKCameraNode 添加到场景的层次结构中(这也可以在 Sprite Kit 编辑器中完成)。

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
}

其次,由于 SKCameraNode 是一个节点,您可以对其应用 SKActions。对于缩小效果,您可以这样做:

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

有关详细信息,请查看 WWDC 2015 talk: What's New In Sprite Kit

一个简单的例子,显示物理体 scales/behaves 在其父节点缩放时适当。点击以将精灵添加到场景中。

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
        }
    }
}