While 循环不适用于 C 中的 bool 语句(初学者!)
While loop not working with bool statements in C (beginner!)
我现在正在学习基础知识,并且正在使用我的大学提供的基本图形库制作一个简单的游戏。
- 有一个弹丸被抛出(其路径已绘制)
- 一个障碍物(一堵墙)- 弹丸无法穿过,所以必须越过
和一个目标(也必须显示为实心,以便在被击中时停止绘制线)
现在我的弹丸正被扔穿墙
问题出在 while 循环
我添加的任何条件(在 (y_displacement < FLOOR_HEIGHT) 之后)都没有效果
(当 y_displacement => FLOOR_HEIGHT(Y 轴反转)时,该射弹自身停止绘制,但任何添加 bool 语句或尝试使用 bool(在#including 之后) 停止绘制射弹线不要进行任何更改。
尝试了 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 ((x_displacement == (X_MAX/2.5)) && ((y_displacement > (Y_MAX/2))))
{
hit_wall = true;
}
你使用 flaot 值,并且由于某些原因(值近似)你几乎永远不会进入这个 if.
你应该使用 >
, >=
, <
, <=
运算符,但在 100% 的情况下它也不会帮助你。
最好的选择是使用 epsilon
(观察误差,邻居)
喜欢
float eps = 0,0000001f;
if ( abs(x_displacement - (X_MAX/2.5) ) < eps
&& y_displacement > ( (Y_MAX/2) - eps ) )
{
hit_wall = true;
}
扩展之前关于浮点等价和舍入误差的答案,另一种方法是将您的 float
或 double
值乘以 10 的某个因数,将小数点移动到对,然后将其转换为 int
或 long it
。然后你可以做一个布尔比较,它将在 integers 上可靠地工作。我提到这一点是因为它有时比另一个答案中描述的 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;
}
我现在正在学习基础知识,并且正在使用我的大学提供的基本图形库制作一个简单的游戏。
- 有一个弹丸被抛出(其路径已绘制)
- 一个障碍物(一堵墙)- 弹丸无法穿过,所以必须越过
和一个目标(也必须显示为实心,以便在被击中时停止绘制线)
现在我的弹丸正被扔穿墙
问题出在 while 循环
我添加的任何条件(在 (y_displacement < FLOOR_HEIGHT) 之后)都没有效果
(当 y_displacement => FLOOR_HEIGHT(Y 轴反转)时,该射弹自身停止绘制,但任何添加 bool 语句或尝试使用 bool(在#including 之后) 停止绘制射弹线不要进行任何更改。
尝试了 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 ((x_displacement == (X_MAX/2.5)) && ((y_displacement > (Y_MAX/2))))
{
hit_wall = true;
}
你使用 flaot 值,并且由于某些原因(值近似)你几乎永远不会进入这个 if.
你应该使用 >
, >=
, <
, <=
运算符,但在 100% 的情况下它也不会帮助你。
最好的选择是使用 epsilon
(观察误差,邻居)
喜欢
float eps = 0,0000001f;
if ( abs(x_displacement - (X_MAX/2.5) ) < eps
&& y_displacement > ( (Y_MAX/2) - eps ) )
{
hit_wall = true;
}
扩展之前关于浮点等价和舍入误差的答案,另一种方法是将您的 float
或 double
值乘以 10 的某个因数,将小数点移动到对,然后将其转换为 int
或 long it
。然后你可以做一个布尔比较,它将在 integers 上可靠地工作。我提到这一点是因为它有时比另一个答案中描述的 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;
}