我试图在一个简单的二维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
而尝试完成的内容,是否有更简单的解决方案?
答案 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")
}
}