我是Swift和SpriteKit的新手,我正在学习如何理解游戏中的控制" Fish&跳闸&#34 ;.精灵节点始终位于视图的中心,它会根据移动您的触摸而旋转,无论您在何处触摸和移动(保持)它都会相应地旋转。
这里的难点在于它与Pan Gesture和简单的触摸位置不同,如图1和图2所示。
对于第一张图片,触摸位置由atan2f处理,然后发送到SKAction.rotate并完成,我可以使其工作。
对于第二张照片,我可以通过设置UIPanGestureRecognizer来实现这一点,但它可以正常工作,但只有在手指围绕初始点移动时才能旋转节点(touchesBegan)。
我的问题是第3张照片,与Fish&旅行游戏,你可以触摸屏幕上的任何地方,然后移动(按住)到任何地方,节点在你移动时仍然旋转,你不必在初始点周围移动手指让节点旋转和旋转平稳而准确。
我的代码如下,它不能很好地运行并且有一些抖动,我的问题是如何以更好的方式实现它?如何使旋转平稳?
有没有办法过滤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
}
}
}
答案 0 :(得分:1)
这不是一个答案(但是 - 希望稍后发布一个/编辑它),但是你可以通过改变movePlayer()
的定义来使你的代码更加'Swifty':
func moveplayer(radian: CGFloat)
到
rotatePlayerTo(angle targetAngle: CGFloat) {
let rotateaction = SKAction.rotate(toAngle: targetAngle, duration: 0.1, shortestUnitArc: true)
thePlayer.run(rotateaction)
}
然后,打电话给它,而不是:
moveplayer(radiant: R1)
使用
rotatePlayerTo(angle: R1)
更具可读性,因为它描述了你做得更好。
此外,你对新角度的旋转恒定为0.1秒 - 所以如果玩家必须进一步旋转,它将旋转得更快。保持转速恒定(以每秒弧度计)会更好。我们可以这样做:
添加以下属性:
let playerRotationSpeed = CGFloat((2 *Double.pi) / 2.0) //Radian per second; 2 second for full rotation
将您的moveShip
更改为:
func rotatePlayerTo(angle targetAngle: CGFloat) {
let angleToRotateBy = abs(targetAngle - thePlayer.zRotation)
let rotationTime = TimeInterval(angleToRotateBy / shipRotationSpeed)
let rotateAction = SKAction.rotate(toAngle: targetAngle, duration: rotationTime , shortestUnitArc: true)
thePlayer.run(rotateAction)
}
这也可能有助于平滑旋转。