【问题标题】:Zoom SKSpriteNode in AND out in Swift在 Swift 中放大和缩小 SKSpriteNode
【发布时间】:2015-06-15 14:49:11
【问题描述】:

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

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

我可以轻松捏缩放整个 SKScene。我还可以通过使用其他 UI 手势(即滑动)和 SKAction 来向上/向下缩放 SKSpiteNode。

基于 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 的帮助,我终于完成了这项工作。我想我会发布工作代码,以防其他人想在 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)
        }
    }

【问题讨论】:

    标签: ios swift sprite-kit


    【解决方案1】:

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

    您可以轻松地缩小到如此远的距离,或者需要多次捏合手势才能将节点恢复到可管理的大小。我建议您使用分步过程,而不是直接使用 scale 属性作为缩放因子。您还应该对比例大小设置最大/最小限制。

    要使用步进过程,您需要创建一个 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]];
            }
        }
    }
    

    【讨论】:

    • 什么!?它对你有用吗?嗯......我刚刚加载它并在我的 iPad 上再次尝试它,当我捏合(将两根手指相互移动)时,它会像应有的那样放大。但是当我松开(将两根手指移开)时,它仍然会放大。这可能是一个错误吗?感谢您提供最小/最大比例,我计划添加它以及从触摸点而不是像现在这样的角落进行缩放。我会尝试调整你的代码,看看我得到了什么。谢谢!!
    • 是不是你在转换ObjC的时候下意识的改正了?? ;-) 从而纠正了我的错误代码。
    • @Freedlun - 我刚刚再次查看了您的捏代码,我发现您正在使用命令“sender.scale = 1.01”对 send.scale 进行硬编码。因此,实际上您忽略了传递的实际值并将其设置为 1.01 取出该行,它应该可以工作。
    • 非常感谢!我在所有试图让它正确的过程中都忽略了那段代码。上面的代码也可以使用它,现在我只需要弄清楚如何从接触点放大它。
    • @Freedlun - 如果我的代码回答了您的问题,请检查是否已回答。
    猜你喜欢
    • 2015-05-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-26
    • 1970-01-01
    • 1970-01-01
    • 2021-11-12
    • 2023-03-29
    • 1970-01-01
    相关资源
    最近更新 更多