我刚接触Swift和SpriteKit,正在学习如何理解游戏“Fish & Trip”中的控制方式。精灵节点始终位于视图中心,并且会根据您的触摸移动而旋转,无论您在哪里触摸并移动(按住),它都会相应地旋转。
这里的难点在于它与图片1和2中所述的平移手势和简单的触摸位置不同。
对于第一张图片,触摸位置经过atan2f处理,然后发送到SKAction.rotate,就完成了,我可以做到这一点。
对于第二张图片,我可以通过设置UIPanGestureRecognizer来实现,但是只有在您围绕初始点(touchesBegan)移动手指时才能旋转节点。
我的问题是针对第三张图片,也就是Fish & Trip游戏中的情况,您可以在屏幕上的任何位置触摸,然后移动(按住)到任何位置,节点仍将随着您的移动而旋转,您不必围绕初始点移动手指来使节点旋转,而且旋转是平滑和准确的。
我的代码如下,它效果不太好,有些抖动,我的问题是如何更好地实现这一点?如何使旋转平滑?
是否有一种方法可以在touchesMoved函数中过滤previousLocation?当我使用此属性时,我总是遇到抖动问题,我认为它报告得太快了。当我使用UIPanGestureRecoginzer时,我没有遇到任何问题,而且非常平滑,所以我想我一定在previousLocation上做错了什么。
func mtoRad(x: CGFloat, y: CGFloat) -> CGFloat {
let Radian3 = atan2f(Float(y), Float(x))
return CGFloat(Radian3)
}
func moveplayer(radian: CGFloat){
let rotateaction = SKAction.rotate(toAngle: radian, duration: 0.1, shortestUnitArc: true)
thePlayer.run(rotateaction)
}
var touchpoint = CGPoint.zero
var R2 : CGFloat? = 0.0
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
for t in touches{
let previousPointOfTouch = t.previousLocation(in: self)
touchpoint = t.location(in: self)
if touchpoint.x != previousPointOfTouch.x && touchpoint.y != previousPointOfTouch.y {
let delta_y = touchpoint.y - previousPointOfTouch.y
let delta_x = touchpoint.x - previousPointOfTouch.x
let R1 = mtoRad(x: delta_x, y: delta_y)
if R2! != R1 {
moveplayer(radiant: R1)
}
R2 = R1
}
}
}