连续使用UIPanGestureRecognizer移动SKSpriteNode

时间:2018-05-30 17:07:25

标签: ios swift sprite-kit uigesturerecognizer skspritenode

我试图在一个简单的二维SKSpriteNode中连续移动SKScene。这涉及移动包含与UIGestureRecognizer平移的相反方向的所有背景节点的数组,并同时为该节点设置动画。

我已经通过实现节点和识别器并在平移时调用其方法来实现该移动:

@objc func didPan(gesture: UIPanGestureRecognizer) {
    let pan = gesture.velocity(in: self.view)
    if gesture.state == .changed {
        for sprites in levelSprites {
            if pan.x > 0 && pan.x > pan.y {
                sprites.run(SKAction.moveTo(x: sprites.position.x - 40, duration: 0.5))
                self.player.run(SKAction(named: "WalkRight")!)
            } else if pan.x < 0 && pan.x < pan.y {
                sprites.run(SKAction.moveTo(x: sprites.position.x + 40, duration: 0.5))
                self.player.run(SKAction(named: "WalkLeft")!)
            } else if pan.y < 0 && pan.x > pan.y {
                sprites.run(SKAction.moveTo(y: sprites.position.y - 30, duration: 0.5))
                self.player.run(SKAction(named: "WalkUp")!)
            } else if pan.y > 0 && pan.x < pan.y {
                sprites.run(SKAction.moveTo(y: sprites.position.y + 30, duration: 0.5))
                self.player.run(SKAction(named: "WalkDown")!)
            }
        }
    }
}

我面临的问题是,这个方法只会移动并为我设置的值设置精灵的动画,以及我必须保持的有限时间以准确匹配动画长度,当我实际想要移动它们时平底锅的持续时间。

我刻意实现了一个用于平移扫描的识别器,scince场景还将包含一个用于控制运动的操纵杆。

对于我未尝试使用UIGestureRecognizer而尝试完成的内容,是否有更简单的解决方案?

1 个答案:

答案 0 :(得分:2)

在用户的单个平移期间,

didPan()被多次调用状态.changed,但不是常规频率。

相反,您应该声明两个全局状态变量,用于保存当前的水平和垂直方向(例如,从左到右,或从右到左,对于第一个方向),并且每次didPan()时更新这些变量调用。

只有当方向发生变化且SKAction个实例应无限循环,而不是仅具有0.5秒的一次性特定持续时间时,您才应运行SKAction实例(请参阅SKAction.repeatForever() in SceneKit API手册)。

此外,您需要确保在运行下一个移动操作之前删除已在运行的移动操作。

最后,在使用州removeAllActions()调用didPan()时致电.ended

enum VerticalState{
   case .none
   case .topToBottom
   case .bottomToTop
}
enum HorizontalState{
   case .none
   case .leftToRight
   case .rightToLeft
}

var verticalState = VerticalState.none
var horizontalState = HorizontalState.none


@objc func didPan(gesture: UIPanGestureRecognizer) {
    let pan = gesture.velocity(in: self.view)
    if gesture.state == .changed {
        for sprites in levelSprites {
            if pan.x > 0 && pan.x > pan.y  && horizontalState <> .leftToRight{
                horizontalState = .none
                verticalState = .none
            } else if pan.x < 0 && pan.x < pan.y && horizontalState <> .rightToLeft{                
                horizontalState = .rightToLeft
                verticalState = .none
            } else if pan.y < 0 && pan.x > pan.y && verticalState <> .bottomToTop{                
                horizontalState = .none
                verticalState = .bottomToTop
            } else if pan.y > 0 && pan.x < pan.y && verticalState <> topToBottom{
                horizontalState = .none
                verticalState = .topToBottom
            }


            switch horizontalState
            {
               case .leftToRight:      
                   sprites.removeActionForKey("movement")    
                   self.player.removeActionForKey("movement")
                   sprites.run(SKAction.repeatForever(SKAction.moveBy(x: -40, y:0, duration: 0.5), forKey:"movement"))
                   self.player.run(SKAction(named: "WalkRight")!, forKey:"movement")
               case .rightToLeft:
                   sprites.removeActionForKey("movement")
                   self.player.removeActionForKey("movement")         
                                      sprites.run(SKAction.repeatForever(SKAction.moveBy(x: 40, y:0,, duration: 0.5), forKey:"movement"))
                   self.player.run(SKAction(named: "WalkLeft")!, forKey:"movement")
               case .none: 
                   break
            }
            switch verticalState
            {
               case .topToBottom:                
                   sprites.removeActionForKey("movement")
                   self.player.removeActionForKey("movement")         
                   sprites.run(SKAction.repeatForever(SKAction.moveBy(x: 0, y:-30, duration: 0.5), forKey:"movement"))
                self.player.run(SKAction(named: "WalkUp")!, forKey:"movement")
               case .bottomToTop:    
                   sprites.removeActionForKey("movement")      
                   self.player.removeActionForKey("movement")         
                   sprites.run(SKAction.repeatForever(SKAction.moveBy(x: 0, y:30,, duration: 0.5), forKey:"movement"))
                   self.player.run(SKAction(named: "WalkDown")!, forKey:"movement")
               case .none:
                   break
            }


        }
    }else if gesture.state == .ended {
         sprites.removeActionForKey("movement")      
         self.player.removeActionForKey("movement")  
    }
}