SKConstraint.zRotation 跨越 +/- PI 鸿沟

SKConstraint.zRotation across +/- PI divide

包含图像中的行为是否可能? (其中节点的锚点位于形状的最右侧。)

我已经确定了解决方法。

我正在为约束使用一个元组,并在 didApplyConstraints 处理程序中自行处理它。

自定义约束的格式假定范围从第一个值开始并逆时针行进直到第二个值。它不允许高于 PI 或低于 -PI 的约束值。此解决方案也不处理大于 2*PI 的总范围。

不跨越 +/- PI 边界的范围是 "normal",可以正常处理。

跨越 +/- PI 边界的范围是 "goofy",必须作为特殊情况处理(如果可能)。

除非您使用 SKPhysicsBody(或手动)跟踪 angular 速度,否则这种特殊情况的解决方案似乎是不可能的。需要此值来识别节点可能 "crossed" 的边界,因此应将其约束到。

// constraint = (CGFloat(M_PI/2), -CGFloat(M_PI/2))

override func didApplyConstraints() {

    var r = rotationSprite.zRotation

    if constraint.0 < constraint.1 { // regular constraint, easy to handle.
        rotationSprite.zRotation = min(max(r, constraint.0),constraint.1)
    }
    else // "goofy" constraint that crosses PI boundary
    {
        if r < constraint.0 && r > constraint.1 {
            if rotationSprite.physicsBody?.angularVelocity < 0 { // clockwise, crossed first value (so long as absolute angular vel is < 2PI
                rotationSprite.zRotation = constraint.0
            }
            else if rotationSprite.physicsBody?.angularVelocity > 0 // counter clockwise, crossed second value (so long as absolute angular vel is < 2PI
            {
                rotationSprite.zRotation = constraint.1
            }
            else
            {
                // If 0 velocity (or no velocity), no way to find out which boundary was crossed.
                rotationSprite.zRotation = constraint.0
                // Probably better to default to closest angle
            }
            rotationSprite.physicsBody?.angularVelocity = 0 // Alternately, multiply by a negative restitution factor.
        }
    }

}