2012-03-02 101 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