C ++ gamedev:将float截断为int

时间:2011-10-31 01:49:31

标签: c++ floating-point rounding

我正在用C ++制作游戏,这是一个可以在舞台上移动的坦克。坦克有一个角度(漂浮,以度为单位,我假设坦克在他的大炮指向右边时为0º),速度(浮动),并且有一个称为“deltaT”(浮动)的时间常数。

当玩家向前移动坦克时,为了计算新坦克,我使用三角学和时间函数的位置物理方程(我的意思是X(t),我不知道它用英语怎么说)阶段中的坐标。

这是我的问题:由于从float到int的通道,不考虑最接近零的值。因此,在某些角度,坦克看起来是旋转的,但是朝不同的方向移动。

这就是我的代码所做的:

1 - 首先,我通过使用坦克移动的角度来分离其组件X和Y的速度:

    float speedX = this->speed * cos(this->angle);
    float speedY = this->speed * sin(this->angle);

2 - 然后使用我上面提到的等式来获得新坐标:

    this->x = (int) ceil(this->x + (speedX * deltaT));
    this->y = (int) ceil(this->y - (speedY * deltaT));

问题从第一步开始:在某些角度,cos或sin的值非常接近于零。 因此,当我将它乘以速度来获得速度X时,我仍然得到一个非常低的数字,然后当我将它乘以deltaT它仍然太低时,最后当应用ceil时,这个数量完全丢失了。

例如,在94º,deltaT = 1.5,速度= 2,假设X的初始值为400,我们有:

speedX = -0.1395...
this->x = 400 //it must be 399.86..., but stays in 400 due to the ceiling

因此,在我的游戏中,坦克显示为旋转,但直接向前移动。此外,有时候它向后移动但向前移动错误,反之亦然。

¿我怎样才能让坦克的方向更准确?提高deltaT的速度或值不是选项,因为它是关于坦克,而不是公式1:P

3 个答案:

答案 0 :(得分:9)

  

如何使水箱的方向更准确?提高deltaT的速度或值不是选项,因为它是关于坦克,而不是公式1:P

您应该将您的位置值存储为float s,即使它们最终用作int用于屏幕定位。这样,你就不会失去你职位的非整数部分。当您进行绘图时,只需在最后投射到int

答案 1 :(得分:5)

始终将坦克的位置保持在float。或者,只让油箱以45度的增量旋转。决定你的游戏是否会使用大致的位置和标题或精确的位置,并一直坚持这个决定。

答案 2 :(得分:0)

你的问题不准确!浮点数学具有24位精度,即正/负1 / 16,777,216。没问题。

这是你的rounding modeceil四舍五入。

尝试:

int x = this->x + (speedX * deltaT) +.5f;

ceil创建的0℃的舍入误差(E); E&。1,如上面所铸造给出-.5&LT,E 1 + 5,其具有一半的绝对误差

另外,避免使用双数学。 ceil是双重版本,您的意思是ceilf。从技术上讲,您的代码会抛出float-> double-> int。你从中得不到任何东西,但需要时间。

最后......真正的问题:

你的准确性问题真的是因为你在积累它! 所以0< E< 1 ... PER FRAME!
在60Hz => 0℃; E< 60 *秒。因此,在一分钟0

无论你怎么回事,这总是一个问题。 而是在舍入之前存储浮点结果。因此,绝对误差总是0

this->XPos += speedX * deltaT;
this->YPos += speedY * deltaT;
this->x = static_cast<int>(this->XPos+.5f);
this->y = static_cast<int>(this->YPos+.5f);

你现在应该顺利移动。

PS:英文单词是&#34;参数&#34;,https://en.wikipedia.org/wiki/Parametric_equation