我正在使用Swift 3.0和Xcode 8.2.1,在运行iOS 10.2的iPhone 6上进行测试。
我只是试图以一个减速的速度旋转SKCameraNode(I.E.它同时具有角速度和加速度)。
这是我目前的解决方案,是的,我知道这很奇怪:
cam.run(
SKAction.repeatForever(
SKAction.sequence([
SKAction.run
{
self.cam.run(SKAction.rotate(toAngle: 0.0, duration: 0.7, shortestUnitArc: true))
},
SKAction.wait(forDuration: 0.1)])))
相机的zRotation从某个非零位置开始,然后调用它。然后它每0.1秒调用一次SKAction.rotate部件。它没有在这里显示,但我让它在3秒后终止。
这提供了我想要的确切效果,因为每次调用SKAction时,zRotation都接近0.0,但是它需要达到的时间保持在0.7,因此它接近0.0的速率放慢速度。
然而,有三件事情中的一件发生在此:
我尝试将waitForDuration从0.1减少到0.01但是它总是执行选项3。
是否有某种"执行规则"在使用相机时我没有注意到?
谢谢!
答案 0 :(得分:2)
您可以使用单个rotate(toAngle:)
动作,当相机的zRotation
接近结束角度并将timingMode
属性设置为.easeOut
时减速。例如,
cam.zRotation = CGFloat.pi
let action = SKAction.rotate(toAngle: 0, duration: duration, shortestUnitArc: true)
// Slows when zRotation is near 0
action.timingMode = .easeOut
cam.run(action)
或者,您可以定义自己的计时功能,通过将timingMode
语句替换为
action.timingFunction = {
time in
// Custom ease-out, modify this as needed
return 1-pow(1-time, 5)
}
此外,您可以使用以下内容计算动作的持续时间,因此无论起始角度(即旋转量)如何,角速度和加速度都是一致的
let duration = TimeInterval(normalizedArcFromZero(angle:cam.zRotation)) * 3
func normalizedArcFromZero(angle:CGFloat) -> CGFloat {
let diff = angle.mod(dividingBy:CGFloat.pi*2)
let arc = CGFloat.pi - (diff + CGFloat.pi).mod(dividingBy:2 * CGFloat.pi)
return abs(arc)/CGFloat.pi
}
最后,因为上面需要一个执行“floored”除法的模数函数(而不是Swift的truncatingRemainder
),所以你需要将它添加到你的项目中
extension CGFloat {
func mod(dividingBy x:CGFloat) -> CGFloat {
return self - floor(self/x) * x
}
}