沿运动方向旋转对象
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
函数将精灵速度的 x
和 y
分量转换为一个角度来实现。您应该仅在精灵的速度大于某个标称值时才旋转精灵,以防止精灵在速度(几乎)为零时重置为零度。
如果我们扩展 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
为零时您的精灵朝右。
有没有比较简单的方法可以旋转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
函数将精灵速度的 x
和 y
分量转换为一个角度来实现。您应该仅在精灵的速度大于某个标称值时才旋转精灵,以防止精灵在速度(几乎)为零时重置为零度。
如果我们扩展 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
为零时您的精灵朝右。