C# XNA 移动 - 可以转动或移动,但不能同时移动
C# XNA Movement - Can either turn or move, not both
我正在尝试制作一个 XNA 宇宙飞船游戏,我可以在其中转弯并开枪等。我 运行 遇到了一个问题,试图得到它,这样我就可以给一艘船一个航路点。出于某种原因,我可以让船移动,也可以让它转弯,但我似乎无法让它同时完成这两项操作。真是st运行ge.
基本上,如果我注释掉我的旋转代码,它会直线飞行,否则它会转弯,但它不会移动它只是停留在原地。
if (GoToWayPoint == true)
{
//CurrentWayPoint.Normalize();
Pos.Normalize();
float angle = (float)Math.Atan2(CurrentWayPoint.X - Pos.X, CurrentWayPoint.Y - Pos.Y);
//Rotate if
if (Rotation > angle && Rotation - TurnSpeed >= angle)
{
Rotation -= TurnSpeed;
}
else if (Rotation < angle && Rotation + TurnSpeed <= angle)
{
Rotation += TurnSpeed;
}
else
{
Rotation = angle;
}
//Move forward if it's facing the right direction
if (Rotation == angle)
{
Velocity.X += (float)Math.Cos(Rotation) * TangentialVelocity * Speed;
Velocity.Y += (float)Math.Sin(Rotation) * TangentialVelocity * Speed;
}
if (Pos == CurrentWayPoint || Vector2.Distance(Pos,CurrentWayPoint) < 10)
{
Pos = CurrentWayPoint;
GoToWayPoint = false;
}
}
//Movement, player controlled
if (PlayerControlled == true)
{
KeyboardState NewKey = Keyboard.GetState();
//Move Up
if (NewKey.IsKeyDown(Keys.Up) || NewKey.IsKeyDown(Keys.W))
{
Velocity.X = (float)Math.Cos(Rotation) * TangentialVelocity * Speed;
Velocity.Y = (float)Math.Sin(Rotation) * TangentialVelocity * Speed;
}
//Move Down
if (NewKey.IsKeyDown(Keys.Down) || NewKey.IsKeyDown(Keys.S))
{
Velocity.X = (float)Math.Cos(Rotation + Math.PI) * TangentialVelocity;
Velocity.Y = (float)Math.Sin(Rotation + Math.PI) * TangentialVelocity;
}
//Move Right
if (NewKey.IsKeyDown(Keys.Right) || NewKey.IsKeyDown(Keys.D))
{
Rotation += TurnSpeed;
}
//Move Left
if (NewKey.IsKeyDown(Keys.Left) || NewKey.IsKeyDown(Keys.A))
{
Rotation -= TurnSpeed;
}
}
//Update Movement
Pos += Velocity;
//Friction
float i = Velocity.X;
float j = Velocity.Y;
Velocity.X = i -= Friction * i;
Velocity.Y = j -= Friction * j;
此外,我有代码可以使用箭头键控制游戏对象。该代码工作正常,并使用相同类型的代码继续前进。
你的问题主要出在这一行:
if (Rotation == angle)
只有当该条件评估为 true
时,您的船才会前进。不幸的是,它永远不会是真的,因为角度是 float
。除非您专门为它们分配相同的值,否则很难让两个浮点数彼此相等(还有其他方法,但在这种情况下它们无关紧要)。
你在这里计算angle
:
float angle = (float)Math.Atan2(CurrentWayPoint.X - Pos.X, CurrentWayPoint.Y - Pos.Y);
这很可能会给你一个小数点后有很多数字的值,比如 1.519573617...
。最重要的是,你只是将你的船转向某个固定的量,TurnSpeed
,这将总是跳过你的精确方向值,改变 angular 方向,然后再次跳过它,无限次。这就是为什么你永远不会前进。
我想到了两种解决方案,您可以尝试一下:
一个是丢掉上面的 if 语句。然后你的飞行器将开始前进,尽管方向错误,但它会在移动时调整方向。
另一种是用一个epsilon来比较Rotation
和angle
。它看起来像这样:
if (Math.Abs(Rotation - angle) < epsilon)
{
Rotation = angle;
// move forward
}
这在比较浮点数时为您提供了一些回旋余地,即 epsilon
的回旋余地。它必须足够大,这样您的 TurnSpeed
就不会跳过整个间隔,但又要足够小,这样它就不会与确切的方向有太大的不同。
关键是你在使用旋转来移动和射击。更准确地说,你使用相同的角度进行拍摄和移动。
您有两个解决方案:
1,移动船只位置 up/down/left/right 而不使用角度。这意味着代码将类似于 if(<em>key up is pressed</em>) ship.position.Y -= ship.speed;
。这意味着你解放了绘画和拍摄的角度。
2、为船创建新的角度变量。现在你有两个(假设 moveAngle
和 shootAngle
)。因此,当您移动船只时使用 moveAngle,当您需要计算射击位置时,使用 shootAngle。现在剩下的就是让您选择绘图的角度了。
奖励:使用左右键从船的方向扫射 90 度。
我正在尝试制作一个 XNA 宇宙飞船游戏,我可以在其中转弯并开枪等。我 运行 遇到了一个问题,试图得到它,这样我就可以给一艘船一个航路点。出于某种原因,我可以让船移动,也可以让它转弯,但我似乎无法让它同时完成这两项操作。真是st运行ge.
基本上,如果我注释掉我的旋转代码,它会直线飞行,否则它会转弯,但它不会移动它只是停留在原地。
if (GoToWayPoint == true)
{
//CurrentWayPoint.Normalize();
Pos.Normalize();
float angle = (float)Math.Atan2(CurrentWayPoint.X - Pos.X, CurrentWayPoint.Y - Pos.Y);
//Rotate if
if (Rotation > angle && Rotation - TurnSpeed >= angle)
{
Rotation -= TurnSpeed;
}
else if (Rotation < angle && Rotation + TurnSpeed <= angle)
{
Rotation += TurnSpeed;
}
else
{
Rotation = angle;
}
//Move forward if it's facing the right direction
if (Rotation == angle)
{
Velocity.X += (float)Math.Cos(Rotation) * TangentialVelocity * Speed;
Velocity.Y += (float)Math.Sin(Rotation) * TangentialVelocity * Speed;
}
if (Pos == CurrentWayPoint || Vector2.Distance(Pos,CurrentWayPoint) < 10)
{
Pos = CurrentWayPoint;
GoToWayPoint = false;
}
}
//Movement, player controlled
if (PlayerControlled == true)
{
KeyboardState NewKey = Keyboard.GetState();
//Move Up
if (NewKey.IsKeyDown(Keys.Up) || NewKey.IsKeyDown(Keys.W))
{
Velocity.X = (float)Math.Cos(Rotation) * TangentialVelocity * Speed;
Velocity.Y = (float)Math.Sin(Rotation) * TangentialVelocity * Speed;
}
//Move Down
if (NewKey.IsKeyDown(Keys.Down) || NewKey.IsKeyDown(Keys.S))
{
Velocity.X = (float)Math.Cos(Rotation + Math.PI) * TangentialVelocity;
Velocity.Y = (float)Math.Sin(Rotation + Math.PI) * TangentialVelocity;
}
//Move Right
if (NewKey.IsKeyDown(Keys.Right) || NewKey.IsKeyDown(Keys.D))
{
Rotation += TurnSpeed;
}
//Move Left
if (NewKey.IsKeyDown(Keys.Left) || NewKey.IsKeyDown(Keys.A))
{
Rotation -= TurnSpeed;
}
}
//Update Movement
Pos += Velocity;
//Friction
float i = Velocity.X;
float j = Velocity.Y;
Velocity.X = i -= Friction * i;
Velocity.Y = j -= Friction * j;
此外,我有代码可以使用箭头键控制游戏对象。该代码工作正常,并使用相同类型的代码继续前进。
你的问题主要出在这一行:
if (Rotation == angle)
只有当该条件评估为 true
时,您的船才会前进。不幸的是,它永远不会是真的,因为角度是 float
。除非您专门为它们分配相同的值,否则很难让两个浮点数彼此相等(还有其他方法,但在这种情况下它们无关紧要)。
你在这里计算angle
:
float angle = (float)Math.Atan2(CurrentWayPoint.X - Pos.X, CurrentWayPoint.Y - Pos.Y);
这很可能会给你一个小数点后有很多数字的值,比如 1.519573617...
。最重要的是,你只是将你的船转向某个固定的量,TurnSpeed
,这将总是跳过你的精确方向值,改变 angular 方向,然后再次跳过它,无限次。这就是为什么你永远不会前进。
我想到了两种解决方案,您可以尝试一下:
一个是丢掉上面的 if 语句。然后你的飞行器将开始前进,尽管方向错误,但它会在移动时调整方向。
另一种是用一个epsilon来比较Rotation
和angle
。它看起来像这样:
if (Math.Abs(Rotation - angle) < epsilon)
{
Rotation = angle;
// move forward
}
这在比较浮点数时为您提供了一些回旋余地,即 epsilon
的回旋余地。它必须足够大,这样您的 TurnSpeed
就不会跳过整个间隔,但又要足够小,这样它就不会与确切的方向有太大的不同。
关键是你在使用旋转来移动和射击。更准确地说,你使用相同的角度进行拍摄和移动。
您有两个解决方案:
1,移动船只位置 up/down/left/right 而不使用角度。这意味着代码将类似于 if(<em>key up is pressed</em>) ship.position.Y -= ship.speed;
。这意味着你解放了绘画和拍摄的角度。
2、为船创建新的角度变量。现在你有两个(假设 moveAngle
和 shootAngle
)。因此,当您移动船只时使用 moveAngle,当您需要计算射击位置时,使用 shootAngle。现在剩下的就是让您选择绘图的角度了。
奖励:使用左右键从船的方向扫射 90 度。