SpriteKit相机动作非常生涩/滞后

时间:2017-01-06 03:13:05

标签: ios swift sprite-kit skaction

我正在使用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的速率放慢速度。

然而,有三件事情中的一件发生在此:

  1. 按预期完美运作
  2. 感觉它停止并且每0.1秒继续
  3. 一旦调用SKAction,摄像机就会立即完全停止作为摄像头运行,并且播放器只是停留在同一位置,直到摄像机切换为止。
  4. 我尝试将waitForDuration从0.1减少到0.01但是它总是执行选项3。

    是否有某种"执行规​​则"在使用相机时我没有注意到?

    谢谢!

1 个答案:

答案 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
    }
}