C# 雪碧旋转
我试图通过使用旋转半径增加和减少旋转来旋转精灵,使其面向鼠标。直到鼠标位于左上角并移动到右上角为止,它都可以正常工作。如果角度差大于当前旋转值,精灵的旋转会增加,否则会减少。所以当它从6.5弧度变为0时,它会逆时针旋转350度,而不是顺时针旋转15度。我和其他人整天都在研究这个问题,不知道如何解决这个问题。我的代码如下:C# 雪碧旋转,c#,math,xna,sprite,C#,Math,Xna,Sprite,我试图通过使用旋转半径增加和减少旋转来旋转精灵,使其面向鼠标。直到鼠标位于左上角并移动到右上角为止,它都可以正常工作。如果角度差大于当前旋转值,精灵的旋转会增加,否则会减少。所以当它从6.5弧度变为0时,它会逆时针旋转350度,而不是顺时针旋转15度。我和其他人整天都在研究这个问题,不知道如何解决这个问题。我的代码如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; us
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个小时写了出来
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);
}
private float-anglerp(浮动nowrap、浮动包裹、浮动lerp){
浮点数c,d;
如果(包裹nowrap>wraps
d=c-nowrap>nowrap-wraps
?MathHelper.Lerp(nowrap、wraps、Lerp)
:MathHelper.Lerp(nowrap,c,Lerp);
}否则如果(包装>无包装){
c=wrapps-MathHelper.TwoPi;
//包裹>nowrap>c
d=包裹-nowrap>nowrap-c
?MathHelper.Lerp(nowrap,c,Lerp)
:MathHelper.Lerp(nowrap、wrapps、Lerp);
}else{return nowrap;}//角度已经相同
返回MathHelper.WrapAngle(d);
}
它将nowrap
向wrapps
值移动。wrapps
角度可以是从0跳到TwoPi再跳回来的角度,因此在本例中,鼠标的角度nowrap
应该是您的对象角度
希望这次我真的能帮上忙。编辑我的道歉。这次我把头从屁股上移开,实际阅读了问题。这里有一个很好的小方法,我今晚花了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);
}
private float-anglerp(浮动nowrap、浮动包裹、浮动lerp){
浮点数c,d;
如果(包裹nowrap>wraps
d=c-nowrap>nowrap-wraps
?MathHelper.Lerp(nowrap、wraps、Lerp)
:MathHelper.Lerp(nowrap,c,Lerp);
}否则如果(包装>无包装){
c=wrapps-MathHelper.TwoPi;
//包裹>nowrap>c
d=包裹-nowrap>nowrap-c
?MathHelper.Lerp(nowrap,c,Lerp)
:MathHelper.Lerp(nowrap、wrapps、Lerp);
}else{return nowrap;}//角度已经相同
返回MathHelper.WrapAngle(d);
}
它将nowrap
向wrapps
值移动。wrapps
角度可以是从0跳到TwoPi再跳回来的角度,因此在本例中,鼠标的角度nowrap
应该是您的对象角度
希望这次我真的能帮上忙。尝试以下内容(这是我制作的坦克游戏中的一些代码,不确定它是否仍然适用于此场景)。我把它精简到最基本的部分:
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点钟)。希望这能为你指明正确的方向 尝试以下内容(这是我制作的坦克游戏中的一些代码,不确定它是否仍然适用于此场景)。我把它精简到最基本的部分:
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点钟)。希望这能为你指明正确的方向 这应该正好与速度更快的方向相反
spin = targetRotation - Rotation;
if (abs(spin) > Math.PI)
spin *= -1;
if (spin > 0
Rotation += turningRadius;
else
Rotation -= turningRadius;
编辑:将180更改为Math.PI这应该只是将方向反转为更快的方向
spin = targetRotation - Rotation;
if (abs(spin) > Math.PI)
spin *= -1;
if (spin > 0
Rotation += turningRadius;
else
Rotation -= turningRadius;
编辑:将180改为数学。让我确定我明白了。你有一个向量
(Cos(Rotation),Sin(Rotation)
,代表你的对象所面对的方向;另一个向量(B.X-a.X,B.Y-a.Y)
代表你想要对象面对的方向;你想知道是否要旋转你的对象(第一个向量)顺时针或逆时针,使其在
第二个向量的方向
简单地说,只需将它们都视为3D向量(设置Z
=0)并获取它们的
- 如果生成的矢量具有正的
分量,则逆时针旋转Z
- 如果它有一个正的
组件,则顺时针旋转Z
- 如果
分量为0,则两个向量是平行的,因此只需检查它们是否朝向相反的方向(并旋转任意一个方向)或相同的方向(无需执行任何操作!)Z
这是因为它定义了叉积。让我确定我理解了。你有一个向量
(Cos(旋转),Sin(旋转)
,表示你的物体所面对的方向;另一个向量(B.X-a.X,B.Y-a.Y)
表示您希望对象朝向的方向;您想知道是顺时针还是逆时针旋转对象(第一个向量)以在
第二个向量的方向
简单地说,只需将它们都视为3D向量(设置Z
=0)并获取它们的
- 如果生成的矢量具有正的
分量,则逆时针旋转Z
- 如果它有一个正的
组件,则顺时针旋转Z
- 如果
分量为0,则两个向量是平行的,因此只需检查它们是否朝向相反的方向(并旋转任意一个方向)或相同的方向(无需执行任何操作!)Z