【问题标题】:While loop not working with bool statements in C (beginner!)While 循环不适用于 C 中的 bool 语句(初学者!)
【发布时间】:2017-09-05 16:46:21
【问题描述】:

我现在正在学习基础知识,并正在使用我的 uni 提供的基本图形库制作一个简单的游戏。

  • 有一个抛射物(其路径已绘制)
  • 障碍物(墙) - 弹丸无法通过,因此必须越过
  • 和一个目标(也必须显示为实线,以便在击中时停止绘制线)

  • 现在我的弹丸正穿过墙壁

  • 问题在于 while 循环

  • 我添加的任何条件(在 (y_displacement

(当 y_displacement => FLOOR_HEIGHT(Y 轴倒置)时,此弹丸会自行停止绘制,但任何添加 bool 语句或尝试使用 bool (在#include 之后)来停止绘制弹丸线时都不要'不做任何改变。

TRIED BOOL FOR WALL(不会改变任何东西):

bool hit_wall = false;


        while ((y_displacement < FLOOR_HEIGHT) && (hit_wall == false))
        {
                time = (x_displacement - X_HAND) / x_velocity; //speed = distance/time
                y_displacement = (Y_HAND - y_velocity * time) - (GRAVITY * pow(time, 2)/2);
                GFX_DrawLineTo(x_displacement, y_displacement, 3);
                x_displacement += 1;

                if ((x_displacement == (X_MAX/2.5)) && ((y_displacement > (Y_MAX/2))))
                   {
                       hit_wall = true;
                   }
        }

}

如果我能设法解决这个问题,那么我应该能够为我的目标做同样的事情..

我的操作有问题吗?

背景:

完整的功能是这样的:

void throwBall(int(x_position), int(y_position))
{
    GFX_SetColour(YELLOW);

    int x_mouse;
    int y_mouse;

    int x_distance;
    int y_distance;

    double angle;

    float initial_velocity;

    float x_velocity;
    float y_velocity;

    float time;

    GFX_MoveTo(X_HAND, Y_HAND);

    GFX_GetMouseCoordinates(&x_mouse, &y_mouse);

    x_distance = x_mouse - X_HAND;
    y_distance = y_mouse - Y_HAND;

    angle = getAngle(x_distance, y_distance);

    initial_velocity = sqrt(pow(x_distance, 2) + pow(y_distance, 2));

    //these have been divided by 5 as the magnitude was too large for the window
    y_velocity = (initial_velocity * sin (angle) - GRAVITY * time)/(X_MAX/256);
    x_velocity = (initial_velocity * cos (angle))/(X_MAX/256);

    float y_displacement;
    float x_displacement;

    x_displacement = X_HAND;
    y_displacement = Y_HAND;


    bool hit_wall = false;


            while ((y_displacement < FLOOR_HEIGHT) && (hit_wall == false))
            {
                    time = (x_displacement - X_HAND) / x_velocity; //speed = distance/time
                    y_displacement = (Y_HAND - y_velocity * time) - (GRAVITY * pow(time, 2)/2);
                    GFX_DrawLineTo(x_displacement, y_displacement, 3);
                    x_displacement += 1;

                    if ((x_displacement == (X_MAX/2.5)) && ((y_displacement > (Y_MAX/2))))
                       {
                           hit_wall = true;
                       }
            }
}

【问题讨论】:

  • 注意:不要明确比较布尔类型。使用自我记录的名称(通常是形容词)并进行测试,例如if ( !hit_wall ) 写你的问题:阅读How to Ask 并提供minimal reproducible example
  • 我不认为我完全明白你在问什么。您写“仍然有效”,那么什么不起作用?您的程序的预期行为和观察到的行为是什么?
  • 这可能是一个问题:x_displacement == (X_MAX/2.5)。您正在比较两个计算出的浮点数(或浮点数和整数)是否相等。请不要那样做。使用 epsilon 或使用 >=/
  • 没有其他工作可做,我可以为您提供:x_displacement == (X_MAX/2.5) 处于休息状态可能不是最好的主意。在像你这样的情况下,浮点等价是无限循环的秘诀

标签: c if-statement while-loop boolean-expression


【解决方案1】:
if ((x_displacement == (X_MAX/2.5)) && ((y_displacement > (Y_MAX/2))))
{
      hit_wall = true;
}

您使用浮点值,并且由于某些原因(值近似),您几乎永远不会进入这种情况。

你应该使用&gt;&gt;=&lt;&lt;= poerators,但在 100% 的情况下它也不会帮助你。

最好的选择是使用epsilon(观察错误,社区)

喜欢

float eps = 0,0000001f;

if ( abs(x_displacement - (X_MAX/2.5) ) < eps
                         &&  y_displacement > ( (Y_MAX/2) - eps ) )
{
     hit_wall = true;
}

【讨论】:

  • epsilon 是这样拼写的 :) 这是一个希腊字母,所以我们不要传播错误的变量名称。
【解决方案2】:

扩展先前关于浮点等价和舍入误差的答案,另一种方法是将您的 floatdouble 值乘以 10 以将小数点向右移动,然后将其转换为intlong it。然后你可以做一个布尔比较,它将在 整数 上可靠地工作。我之所以提到这一点,是因为它有时比其他答案中描述的 epilson 方法(您还必须对其进行绝对值处理)更容易编码和阅读。

要认识到的重要一点是乘以或设置 epsilon 为 10 的因数。

不要发疯并在不需要时乘以 1e9 或设置 epsilon = 1e-9,因为那样会重新引入相同的问题。

例如,如果您的距离变量以 为单位,那么您需要认识到您不需要大于 ??? 的分辨率。让我们以 1/100 毫米为例……就您而言,1.230012345mm == 1.230456789mm。所以然后乘以 1e5 然后转换为 int 或执行epsilon=1e-5;。同样的原则适用于英寸单位,通常不需要大于 0.0001" 的分辨率,因此乘以 1e4 或 epsilon = 1e-4。

/* example */

# define D2I    1e2   /* dbl to int factor, 0.01mm resolution */

double x_displacement;   /* units of millimeters for this example*/
double y_displacement;   /* units of millimeters for this example*/


/* whatever previous calculations result in...
   x_displacement having value of   3.00000249687738566
   y_displacement having value of 120.00000085639820699
   out past 6 or so decimal places a float or double will have arbitrary numbers, so don't multiply by some huge 1e12 number
*/


if ( ( (int)(x_displacement * D2I) == (int)((X_MAX / 2.5) * D2I ) ) &&
     ( (int)(y_displacement * D2I ) > (int)((Y_MAX / 2  ) * D2I ) )
   )
{
   hit_wall = true;
}

【讨论】:

    猜你喜欢
    • 2016-04-14
    • 2021-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-24
    • 2013-03-04
    • 2015-07-14
    • 2013-09-26
    相关资源
    最近更新 更多