2012-03-02 150 views
1

我想旋轉一個精靈來面對鼠標通過使用旋轉半徑增加和減少旋轉。它的工作正常,直到鼠標左上角並移動到右上角。我擁有它,所以如果角度差異大於當前的旋轉值,精靈的旋轉會增加,否則它會減少。所以當它從6.5弧度變爲0時,它逆時針旋轉350度 - 某些度數,而不是順時針旋轉15度 - 某些度數。我和其他人一整天都在爲此工作,並不知道如何解決這個問題。我的代碼如下:雪碧旋轉XNA

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Microsoft.Xna.Framework.Graphics; 
using Microsoft.Xna.Framework; 
using Microsoft.Xna.Framework.Input; 
using System.IO; 

namespace Physics 
{ 
public class Ship 
{ 
    public Texture2D Texture { get; set; } 
    public Vector2 Position { get; set; } 
    public double Rotation { get; set; } 
    MouseState prevState, currState; 

    Vector2 A, B; 

    public const double NINETY_DEGREES = 1.57079633; 

    double turningRadius = 2 * (Math.PI/180); 
    double targetRotation, rotationDifferential; 

    public Ship(Texture2D texture, Vector2 position) 
    { 
     Texture = texture; 
     Position = position; 
     A = new Vector2(Position.X, Position.Y); 
     B = new Vector2(Mouse.GetState().X, Mouse.GetState().Y); 
     Rotation = 0; 
    } 

    public void Update() 
    { 
     currState = Mouse.GetState(); 
     A.X = Position.X; 
     A.Y = Position.Y; 
     B.X = currState.X; 
     B.Y = currState.Y; 

     if (B.Y > A.Y) 
      if (B.X > A.X) //Bottom-right 
       targetRotation = Math.Atan((B.Y - A.Y)/(B.X - A.X)) + NINETY_DEGREES; 
      else //Bottom-left 
       targetRotation = (Math.Atan((A.X - B.X)/(B.Y - A.Y))) + (NINETY_DEGREES * 2); 
     else 
      if (B.X > A.X) //Top-right 
       targetRotation = Math.Atan((B.X - A.X)/(A.Y - B.Y)); 
      else //Top-Left 
       targetRotation = Math.Atan((A.Y - B.Y)/(A.X - B.X)) + (NINETY_DEGREES * 3); 

     if (Rotation > targetRotation) 
      Rotation -= turningRadius; 
     else 
      Rotation += turningRadius; 

     prevState = currState; 
    } 

    public void Draw(SpriteBatch spriteBatch) 
    { 
     spriteBatch.Draw(Texture, Position, null, Color.White, (float)Rotation, new Vector2(Texture.Width/2, Texture.Height/2), 0.5f, 
      SpriteEffects.None, 0.0f); 
    } 
} 

}

回答

3

讓我知道我的理解。你有一個矢量(Cos(Rotation), Sin(Rotation)代表你的物體面向哪個方向;另一個向量(B.X-A.X, B.Y-A.Y)代表你想要的方向想要;並且您想知道是否要順時針或逆時針旋轉對象(第一個矢量)以面向第二個矢量的方向 ?

操作簡單,只需對待他們既作爲3D矢量(設置Z = 0)並採取他們cross product

  • 如果得到的載體具有正Z部件,逆時針旋轉
  • 如果它具有正Z組分,按順時針方向旋轉
  • 如果Z分量爲0,這兩個矢量平行,所以只是檢查他們是否面臨相反的方向(和任一方向旋轉)或相同的方向(無所事事!)

由於定義了交叉產品的right-hand rule,這是有效的。

+0

任何想法如果我只有兩個弧度的浮動角度如何做到這一點? – Jack 2015-07-20 08:20:03

+0

@傑克:這已經在答案?爲了將角度轉換爲方向矢量,它只是'(Cos(旋轉),Sin(旋轉))' – 2015-07-20 18:03:00

+0

我想我想知道是否有這樣做的方法,而不將浮點數轉換爲Vector3。似乎有點...無關經歷該轉換並再次回到浮動狀態? – Jack 2015-07-20 18:24:25

0

編輯我的道歉我刪除了我的腦袋從我的後路和實際讀取的問題這個時候。所以這裏有一個很好的方法,我花了大約3小時寫下今晚。

private float AngleLerp(float nowrap, float wraps, float lerp) { 

    float c, d; 

    if (wraps < nowrap) { 
     c = wraps + MathHelper.TwoPi; 
     //c > nowrap > wraps 
     d = c - nowrap > nowrap - wraps 
      ? MathHelper.Lerp(nowrap, wraps, lerp) 
      : MathHelper.Lerp(nowrap, c, lerp); 

    } else if (wraps > nowrap) { 
     c = wraps - MathHelper.TwoPi; 
     //wraps > nowrap > c 
     d = wraps - nowrap > nowrap - c 
      ? MathHelper.Lerp(nowrap, c, lerp) 
      : MathHelper.Lerp(nowrap, wraps, lerp); 

    } else { return nowrap; } //Same angle already 

    return MathHelper.WrapAngle(d); 
} 

它lerps的nowrapwraps值。 wraps角度可以是從0跳到TwoPi的角度,並且在這種情況下是鼠標的角度。 nowrap應該是你的物體角度。

希望這次我確實很有幫助。

+0

據我所知,所做的只是減少從x到Pi和-Pi之間的角度。文件有點缺乏。這看起來很有前途,但並不能控制角度變化的速度,這是遊戲的基礎。對於什麼,以及如何使用它有點幫助將是很好的:-)。另外,當我實現它時,我將旋轉設置爲MathHelper.WrapAngle(targetRotation),並簡單地設置旋轉角度。我需要一個平穩,緩慢的過渡... – Jack 2012-03-02 04:16:14

0

請嘗試以下操作(這是我製作的坦克遊戲的一些代碼,不確定它是否仍適用於此場景)。我修剪下來的要領:

using System; 
using Microsoft.Xna.Framework.Graphics; 
using Microsoft.Xna.Framework; 
using Microsoft.Xna.Framework.Input; 

namespace Physics 
{ 
    public class Ship 
    { 
     public Texture2D Texture { get; set; } 
     public Vector2 Position { get; set; } 
     public double Rotation { get; set; } 
     private MouseState currState; 

     public Ship(Texture2D texture, Vector2 position) 
     { 
      Texture = texture; 
      Position = position; 
      Rotation = 0; 
     } 

     public void Update() 
     { 
      currState = Mouse.GetState(); 

      var mouseloc = new Vector2(currState.X, currState.Y); 
      Vector2 direction = Position - mouseloc; 
      Rotation = Math.Atan2(direction.Y, direction.X) + MathHelper.PiOver2; 
     } 

     public void Draw(SpriteBatch spriteBatch) 
     { 
      spriteBatch.Draw(Texture, Position, null, Color.White, (float) Rotation, 
          new Vector2(Texture.Width/2, Texture.Height/2), 0.5f, 
          SpriteEffects.None, 0.0f); 
     } 
    } 
} 

我認爲你只是需要更多的數學修改的旋轉速度,我會回來,如果我拿出一個解決方案。 此外,這段代碼會根據精靈的默認旋轉而變化。在我的例子中,它假定精靈朝下(6點鐘)。希望這能指出你正確的方向!

1

這應該只是反向,以較快者爲準。

spin = targetRotation - Rotation; 
if (abs(spin) > Math.PI) 
    spin *= -1; 
if (spin > 0 
    Rotation += turningRadius; 
else 
    Rotation -= turningRadius; 

編輯:改變180 Math.PI

+0

如果只是它的工作。 – 2017-06-24 05:19:09