我是 Swift 和 SpriteKit 的新手,正在学习理解“Fish & Trip”游戏中的控件。 sprite 节点始终位于 View 的中心,它会根据您触摸的移动而旋转,无论您在哪里触摸和移动(按住)它都会相应地旋转。
这里的困难在于它不同于我在图 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
}
}
}
最佳答案
这不是一个答案(但是 - 希望稍后发布一个/将其编辑成一个),但是您可以通过更改 movePlayer()
的定义使您的代码更“敏捷”来自:
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)
}
这也有助于平滑旋转。
关于ios - 使用移动触摸旋转 Sprite 节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46088188/