我不是问如何实现这一点,它很简单。我遇到的麻烦是花车。这是我的代码:
Position += mVelocity;
if (!Keyboard.GetState().IsKeyDown(Keys.Left) && !Keyboard.GetState().IsKeyDown(Keys.Right) && !Keyboard.GetState().IsKeyDown(Keys.Down) && !Keyboard.GetState().IsKeyDown(Keys.Up))
{
if (mVelocity.X != 0.0F)
{
if (mVelocity.X > 0.0F)
mVelocity.X -= mFriction;
if (mVelocity.X < 0.0F)
mVelocity.X += mFriction;
}
if (mVelocity.Y != 0.0F)
{
if (mVelocity.Y > 0.0F)
mVelocity.Y -= mFriction;
if (mVelocity.Y < 0.0F)
mVelocity.Y += mFriction;
}
}
Console.WriteLine(mVelocity.X + ", " + mVelocity.Y);
mFriction为0.2F。
问题是,如果我以正速度(X或Y)移动播放器,则摩擦会按预期进行,并且其速度会降低到0.0。但是,如果我以负速度移动他,则摩擦会增加,并且由于某种原因,摩擦不会在0.0处停止,而是会在停止前增加到0.2。因此,我让一位玩家移动,然后放开按键时,他开始朝相反的方向缓慢滑动。为什么是这样?我该如何解决?
另外,我尝试了以下代码进行测试:
if (mVelocity.X == 0.2F)
mVelocity.X = 0.0F;
if (mVelocity.Y == 0.2F)
mVelocity.Y = 0.0F;
但这给了我与未添加代码完全相同的结果。显然,0.2F不等于0.2F。这可能是什么?
最后,在调试输出中,当播放器处于静止状态(假设停止)时,其x和y的速度(取决于我的移动方式)为2.980232E-08。我不明白如果我将他的速度设置为1,并且每帧精确地减去0.2,为什么它会以除1.0、0.8、0.6、0.4、0.2、0.0之外的其他方式运行?此后,如果他静止不负运动,则x和y的速度(再次取决于我的移动方式)为0.2。为什么不走-1,-0.8,-0.6,-0.4,-0.2、0.0?而不是从0.0超出为0.2。
这一切对我来说几乎是毫无意义的,如果有人能为我解决这个问题,我将不胜感激。任何替代解决方案也可以接受。如果需要更多代码或澄清说明,我很乐意提供。
最佳答案
问题是您的相等性测试由于不精确而失败,例如,角色继续移动一帧。
浮点数从根本上讲是不精确的,因此理论上2.0f * 5.0f不一定== 10.0f。它可能是9.999999f或10.000001f。不要测试两个浮点数是否相等:测试它们是否在足够小的间隔内,即:
// test approximate equality between f1 and f2
bool areEqual(float f1, float f2) {
return Math.Abs(f1 - f2) < EqualityThreshold; // where EqualityThreshold is a small constant
}
另请阅读http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
关于c# - 与XNA和C#摩擦,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10221678/