SKConstraint.z转换+/- PI划分

时间:2015-03-01 01:31:48

标签: sprite-kit

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

Image of SKConstraint limiting the rotation of a node to the left half of an arc defined by the limits -PI/2 and PI/2?

1 个答案:

答案 0 :(得分:1)

我已确定了一种解决方法。

我使用元组作为约束并在didApplyConstraints处理程序中自己处理它。

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

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

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

除非您使用SKPhysicsBody(或手动)跟踪角速度,否则似乎无法解决特殊情况。需要该值来识别节点可能跨越哪个边界"因此应该限制在。

// 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.
        }
    }

}