有没有人经历zRotation大于2 Pi?

时间:2016-10-30 20:42:50

标签: sprite-kit rotation swift3

我使用Swift3得到zRotation的值小于/大于 - / + pi(例如7.41137313842773,弧度大约为0.5Pi)。当使用下面描述的方法旋转节点时会发生这种情况。

代码是

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch in touches {
        newLocation = touch.location(in: self)
        turnAngle = atan2(newLocation.y - lastLocation.y - mySprite.position.y, newLocation.x - lastLocation.x - mySprite.position.x)
        mySprite.run(SKAction.rotate(byAngle: turnAngle, duration: 0.1))
        lastLocation = newLocation
        print("mySprite zRotation: \(mySprite.zRotation)")
    }
}

当sprite旋转到pi / 2(绝对值)时,我也注意到sprite中的抖动跳跃。如果这是正常行为,有没有办法重新计算 - / + Pi或0-2Pi之间的zRotation?

2 个答案:

答案 0 :(得分:1)

我相信你的代码有两点要分析: ActionView::Helpers::UrlHelperSKAction

第一个(zRotation)应该被考虑(不是关于这个问题)。如果你想推出SKAction喜欢&#39;旋转&#39;在一个循环中,因为它有一个持续时间你应该检查这个动作是否在启动另一个之前完成。一个例子:

SKAction

说到extension SKNode { func actionForKeyIsRunning(key: String) -> Bool { return self.action(forKey: key) != nil ? true : false } } if !self.mySprite.actionForKeyIsRunning(key: "rotation") { self.mySprite.run(SKAction.rotate(byAngle: turnAngle, duration: 0.1),withKey:"rotation") } 和您的问题,您的错误zRotation值的原因是因为您正在使用某个操作。 zRotation是节点属性:在模拟的每个步骤中不更新正在进行动画的节点的属性。您可以设置zRotation来轮换您的节点:

zRotation

或创建一个物理体并设置角速度。

有关self.mySprite.zRotation = turnAngle 和节点属性的详细信息,请查看official Apple doc哪里有此注释:

  

何时不应使用操作

     

虽然行动有效,但创建和创建成本   执行它们。如果要更改节点的属性   动画的每一帧和那些变化都需要重新计算   每一帧,你最好直接对节点进行更改   而不是使用行动这样做。有关您的位置的更多信息   可能会在您的游戏中执行此操作,请参阅Advanced Scene Processing

答案 1 :(得分:1)

正如@PietroPepe指出的那样,你正在将行动叠加在另一个之上。让我们分解您的代码:

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch in touches {

这告诉我们,您的触摸通话将在触摸的整个生命周期中多次完成。即使采用快速触摸和向上动作,也可以通过此方法至少进行2次调用。

    newLocation = touch.location(in: self)
    turnAngle = atan2(newLocation.y - lastLocation.y - mySprite.position.y, newLocation.x - lastLocation.x - mySprite.position.x)

此代码的要点是让精灵在触摸从最后位置变为当前位置时移动

    mySprite.run(SKAction.rotate(byAngle: turnAngle, duration: 0.1))
    lastLocation = newLocation
    print("mySprite zRotation: \(mySprite.zRotation)")
}

}

最后,代码的这一点说是在1/10秒内完成。

现在让我们来看一个场景。我们触摸屏幕,移动它,然后放手。

执行它所花费的时间是4帧,这意味着1个touchBegan,2个touchMoved和1个touchEnded。

在我们的toucheMoved事件中,我们每次计算60度的变化。

现在一帧是1/60秒,请记住。

我们的旋转事件将需要1/10秒从0到60,所以6/60秒,6帧。

这意味着我们每帧移动10度。

现在我们来到rotateBy的第二帧。

与上面第一帧相同的逻辑将适用,因此我们现在将进行另一系列旋转10度。

这意味着我们现在有2个事件以每个6度旋转我们的精灵。

所以时间表如下:

框架:0 1 2 3 4 5 6 7          +10 +10 +10 +10 +10 +10              +10 +10 +10 +10 +10 +10

请注意轮换结束和开始之间的不一致行为?这就是事情看起来很复杂的原因。

现在,我不确定你想要的效果,但如果我这样做,我会设置zRotation而不是使用动作。

如果您正在寻找延迟效果,请使用withKey函数上的run参数,以便只运行1个操作,并使用SKAction.rotateTo始终使用精灵旋转到最后可能的触摸位置。这当然意味着您需要跟踪首次触摸的时间,而不是最后一次触摸时。

根据所需的效果,这也有点棘手,因为您可能需要跟踪调用的touchesMoved个事件数之间经过的时间,并将时间差应用于您的持续时间,所以基本上{ {1}},