沿运动方向旋转对象

Rotate an object in its direction of motion

有没有比较简单的方法可以旋转SKSpriteNode,使其始终朝向移动的方向?我的 class Gamescene 有一个对象系统,它们的相关物理体在碰撞时会相互施加脉冲。这使得准确跟踪物体移动的方向变得相对困难。一些物体的形状也不规则,这让事情变得更加混乱。我曾尝试使用三角函数(例如反正切),但它仅在非常特殊的情况下才能按预期工作。是否有办法找出 SKSpriteNode 轨迹的角度,以便我可以将对象旋转到该角度?感谢您的任何帮助,您可以提供!

编辑:

我为 CGVector 创建了一个扩展,并尝试在两个对象发生碰撞后沿其速度方向旋转 SKSpriteNode(感谢 0x141E 的想法),但它似乎无法正常工作

func didBeginContact(contact: SKPhysicsContact) {
    var firstBody : SKPhysicsBody = contact.bodyA
    var secondBody : SKPhysicsBody = contact.bodyB
    if ((firstBody.categoryBitMask == PhysicsCatagory.Blade) && (secondBody.categoryBitMask == PhysicsCatagory.Laser))
    {
        if (secondBody.node != nil)
        {
            if (saberAngle <= 0 && LCR == 1) // Blade pointing right
            {
                let rebound = CGVectorMake(-reboundStrength*sin(1.5707 + saberAngle), reboundStrength*cos(1.5707 + saberAngle))
                secondBody.applyImpulse(rebound)
            }
            else if (saberAngle > 0 && LCR == -1) // Blade pointing left
            {
                let rebound = CGVectorMake(reboundStrength*sin(1.5707 - saberAngle), reboundStrength*cos(1.5707 - saberAngle))
                secondBody.applyImpulse(rebound)
            }
            if (secondBody.velocity.speed() > 0.01){
                (secondBody.node as! SKSpriteNode).zRotation = secondBody.velocity.angle() - offset
            }
        }
    }
}

我没有在 didSimulatePhysics() 方法中这样做,因为有时我尝试旋转的节点不存在,我会得到类似 "Use of unresolved identifier 'sprite'"

的错误

编辑:

我通过简单地创建和 运行 一个名为 rotate 的动作来使它工作,该动作将精灵旋转到 secondBody.velocity.angle() - 偏移量,但我仍然很好奇为什么我的代码是之前工作过^^

沿运动方向旋转精灵相当简单。您可以通过使用 atan2 函数将精灵速度的 xy 分量转换为一个角度来实现。您应该仅在精灵的速度大于某个标称值时才旋转精灵,以防止精灵在速度(几乎)为零时重置为零度。

如果我们扩展 CGVector 以通过

计算速度分量的速度和角度
extension CGVector {
    func speed() -> CGFloat {
        return sqrt(dx*dx+dy*dy)
    }
    func angle() -> CGFloat {
        return atan2(dy, dx)
    }
}

我们可以通过

旋转精灵使其面向其运动方向
override func didSimulatePhysics() {
    if let body = sprite.physicsBody {
        if (body.velocity.speed() > 0.01) {
            sprite.zRotation = body.velocity.angle() - offset
        }
    }
}

其中 offset = CGFloat(M_PI_2) 如果当 zRotation 为零时您的精灵朝上,offset = 0 如果当 zRotation 为零时您的精灵朝右。