是否有一种相对简单的旋转SKSpriteNode的方法,使其始终面对其移动方向?我班的Gamecene有一个带有相对物理实体的对象系统,它们在碰撞时会相互施加脉冲。这使得很难准确地跟踪对象的移动方向。某些对象的形状也不规则,这会使事情更加混乱。我尝试使用三角函数(例如反正切),但是它仅在非常特殊的情况下可以正常使用。可能有一种方法可以找出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()方法中执行此操作,因为有时我尝试旋转的节点将不存在,并且会出现诸如“使用未解析的标识符’sprite’”的错误。
我可以通过简单地创建并运行一个名为turn的动作来使它工作,该动作将sprite旋转到secondBody.velocity.angle()-offset,但是我仍然好奇为什么我的代码在^^之前不起作用
沿其运动方向旋转精灵非常简单。您可以使用函数将子画面速度的x和y分量转换为一个角度来实现atan2。仅当精灵的速度大于某个标称值时,才应旋转它,以防止在精灵的速度(接近)为零时将精灵重置为零度。
x
y
atan2
如果我们扩展CGVector以通过速度分量计算速度和角度
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是零。
offset = CGFloat(M_PI_2)
zRotation
offset = 0