放大和缩小 SKSpriteNode Swift

Zoom SKSpriteNode in AND out in Swift

首先,我已经看到并尝试实施类似问题的其他答案here, here and here。问题是我去年用 Swift 开始为 iOS 编程并且(遗憾的是)我没有先学习 ObjC(是的,它现在在我的待办事项列表上)。 ;-)

所以请看一下,看看您是否可以帮助我解决这个问题。

我可以轻松缩放整个 SKScene。我还可以通过使用其他 UI 手势(即滑动)和 SKActions 来缩放 SKSpiteNode up/down。

基于 this post 我已经将 SKAction 应用于 UIPinchGestureRecognizer,它可以完美地放大,但我无法让它缩小。

我错过了什么?

这是我在示例项目中的代码:

class GameScene: SKScene {

var board = SKSpriteNode(color: SKColor.yellowColor(), size: CGSizeMake(200, 200))

func pinched(sender:UIPinchGestureRecognizer){
    println("pinched \(sender)")
    // the line below scales the entire scene
    //sender.view!.transform = CGAffineTransformScale(sender.view!.transform, sender.scale, sender.scale)
    sender.scale = 1.01

    // line below scales just the SKSpriteNode
    // But it has no effect unless I increase the scaling to >1
    var zoomBoard = SKAction.scaleBy(sender.scale, duration: 0)
    board.runAction(zoomBoard)
}

// line below scales just the SKSpriteNode
func swipedUp(sender:UISwipeGestureRecognizer){
    println("swiped up")
    var zoomBoard = SKAction.scaleBy(1.1, duration: 0)
    board.runAction(zoomBoard)
}

// I thought perhaps the line below would scale down the SKSpriteNode
// But it has no effect at all
func swipedDown(sender:UISwipeGestureRecognizer){
    println("swiped down")
    var zoomBoard = SKAction.scaleBy(0.9, duration: 0)
    board.runAction(zoomBoard)
}

override func didMoveToView(view: SKView) {

    self.addChild(board)

    let pinch:UIPinchGestureRecognizer = UIPinchGestureRecognizer(target: self, action: Selector("pinched:"))
    view.addGestureRecognizer(pinch)


    let swipeUp:UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: Selector("swipedUp:"))
    swipeUp.direction = .Up
    view.addGestureRecognizer(swipeUp)

    let swipeDown:UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: Selector("swipedDown:"))
    swipeDown.direction = .Down
    view.addGestureRecognizer(swipeDown)


}

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    // should I be using this function instead?


}

感谢@sangony 的帮助,我终于完成了这项工作。我想我会 post 工作代码以防其他人想在 Swift.

中看到它
var board = SKSpriteNode(color: SKColor.yellowColor(), size: CGSizeMake(200, 200))

var previousScale = CGFloat(1.0)

func pinched(sender:UIPinchGestureRecognizer){
    if sender.scale > previousScale {
        previousScale = sender.scale
        if(board.size.height < 800) {
            var zoomIn = SKAction.scaleBy(1.05, duration:0)
            board.runAction(zoomIn)
        }
    }
    if sender.scale < previousScale {
        previousScale = sender.scale
        if(board.size.height > 200) {
            var zoomOut = SKAction.scaleBy(0.95, duration:0)
            board.runAction(zoomOut)
        }
    }

我尝试了您的代码(在 Objective C 中)并使用捏合来放大和缩小它。我认为您的代码没有任何问题,但您可能没有考虑比例因子,因为它们被放置在不断变化的精灵大小上。

您可以轻松地缩小或缩小到需要多次捏合手势才能使节点恢复到可管理的大小。我建议您使用步进过程,而不是直接使用比例 属性 作为缩放系数。您还应该有 max/min 规模限制。

要使用步骤过程,您创建一个 CGFloat ivar previousScale 来存储最后一个比例值以确定当前捏合是放大还是缩小。然后将新传递​​的 sender.scale 与 ivar 进行比较,并根据比较放大或缩小。

应用最小和最大缩放限制以在达到它们后停止缩放。

下面的代码是在 Obj-C 中,但我相信你能理解它的要点:

首先声明你的ivar float float previousScale;

- (void)handlePinch:(UIPinchGestureRecognizer *)sender {

    NSLog(@"pinchScale:%f",sender.scale);

    if(sender.scale > previousScale) {
        previousScale = sender.scale;

        // only scale up if the node height is less than 200
        if(node0.size.height < 200) {
            // step up the scale factor by 0.05
            [node0 runAction:[SKAction scaleBy:1.05 duration:0]];
        }
    }

    if(sender.scale < previousScale) {
        previousScale = sender.scale;

        // only scale down if the node height is greater than 20
        if(node0.size.height > 20) {
            // step down the scale factor by 0.05
            [node0 runAction:[SKAction scaleBy:0.95 duration:0]];
        }
    }
}