Ios 使用UIPangestureRecognitor连续移动SKSpriteNode

Ios 使用UIPangestureRecognitor连续移动SKSpriteNode,ios,swift,sprite-kit,uigesturerecognizer,skspritenode,Ios,Swift,Sprite Kit,Uigesturerecognizer,Skspritenode,我试图在一个简单的二维SKScene中连续移动SKSpriteNode。这包括将包含所有背景节点的数组沿UIgestureRecognitor平移的相反方向移动,同时设置节点动画 我已经通过实现节点和识别器并在平移时调用其方法实现了移动: @objc func didPan(gesture: UIPanGestureRecognizer) { let pan = gesture.velocity(in: self.view) if gesture.state == .change

我试图在一个简单的二维
SKScene
中连续移动
SKSpriteNode
。这包括将包含所有背景节点的数组沿
UIgestureRecognitor
平移的相反方向移动,同时设置节点动画

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

@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")!)
            }
        }
    }
}
@objc func didPan(手势:uipangestureignizer){
让平移=手势.速度(在:self.视图中)
如果手势.state==.changed{
用于levelSprites中的精灵{
如果pan.x>0&&pan.x>pan.y{
sprites.run(SKAction.moveTo(x:sprites.position.x-40,持续时间:0.5))
self.player.run(SKAction(命名为:“WalkRight”)!)
}如果pan.x<0&&pan.xpan.y,则为else{
sprites.run(SKAction.moveTo(y:sprites.position.y-30,持续时间:0.5))
self.player.run(SKAction(命名为:“WalkUp”)!)
}如果pan.y>0&&pan.x
我面临的问题是,当我真的想在平移过程中移动精灵时,该方法仅根据我设置的值和我必须保持的有限时间来移动精灵并设置其动画,以精确匹配动画长度

我特意实现了一个识别器,用于平移而不是滑动,因为该场景还将包含一个操纵杆,用于稍后控制移动

是否有一个更简单的解决方案来解决我不使用
UIgestureRecognitor
的问题?

didPan()
在用户的一次平移过程中被多次调用,但不是以常规频率

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

您应该仅在方向改变时运行
SKAction
实例,并且那些
SKAction
实例应该无限循环,而不是一次性的特定持续时间为0.5秒(请参阅SceneKit API手册中的
SKAction.repeatForever()

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

最后,当使用state
调用
didPan()
时,调用
removeAllActions()

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")  
    }
}
enum垂直状态{
没有
凯斯,托普托姆
箱底托普
}
枚举水平状态{
没有
凯斯,左向右
案例。从右到左
}
变量verticalState=verticalState.none
var horizontalState=horizontalState.none
@objc func didPan(手势:UIPANGESTURE识别器){
让平移=手势.速度(在:self.视图中)
如果手势.state==.changed{
用于levelSprites中的精灵{
如果pan.x>0&&pan.x>pan.y&&horizontalState.leftToRight{
水平状态=.none
垂直状态=.none
}如果pan.x<0&&pan.xpan.y&&verticalState.bottomToTop{
水平状态=.none
垂直状态=.bottomToTop
}否则,如果pan.y>0&&pan.x
didPan