didPan()
вызывается несколько раз с состоянием .changed
во время одного панорамирования от пользователя, но не с регулярной частотой.
Вместо этого вы должны объявить две глобальные переменные состояния, которые сохраняют текущую горизонтальнуюи вертикальные направления (слева направо или справа налево, например, для первого) и обновлять эти переменные каждый раз, когда вызывается didPan()
.
Вы должны запускать экземпляр SKAction
только тогда, когда меняется направление, и эти экземпляры SKAction
должны циклически выполняться бесконечно, а не иметь единовременную конкретную длительность 0,5 с (см. SKAction.repeatForever()
в 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")
}
}