gpt4 book ai didi

使用无用的 printf 调用修复了条件返回值错误

转载 作者:太空宇宙 更新时间:2023-11-04 03:11:50 27 4
gpt4 key购买 nike

我试图为我的简单游戏(学校项目)编写一个简单的碰撞检测函数,但直到我添加了一个无意义的 printf 行(最初它旨在协助调试)并且它都以某种方式工作。我想知道那个错误是什么?以及如何用更“正确”的方式修复它。谢谢。

这是我的函数(变量“rect”(矩形)是一个标准的 SDL 结构,它有 4 个整数成员代表它的高度、宽度和角的 x 和 y):

bool collision(SDL_Rect *rect1, SDL_Rect *rect2) {
//chekcs to see if rect2 is totally outside of boundaries of rect1
static bool collided;
if (rect1->y > rect2->y + rect2->h) {
printf("");
collided = false;
return collided;
}
if (rect1->y + rect1->h < rect2->y) {
printf("");
collided = false;
return collided;
}
if (rect1->x > rect2->x + rect2->w) {
printf("");
collided = false;
return collided;
}
if (rect1->x + rect1->w < rect2->x) {
printf("");
collided = false;
return collided;
}
//returns 1 if none of above is true

collided = 1;
return collided;
}

编辑:我使用 static bool 是因为我试图让 Visual Studio 在监 window 口中显示 bool 变量的值,即使它(变量)超出范围,它也不起作用,我忘记删除 static。问题是我是否使用静态。

编辑 2:这是调用上面函数的函数(我知道 digonalMovement 需要一个小的修复来使对角线移动时两个方向的速度变慢(目前只有 1 个变慢),但这应该与手头的问题):

void player_movement_calc(int player_nr, SDL_Rect char_rects[], Char character[]) {
// determine velocity
character[player_nr].x_vel = character[player_nr].y_vel = 0;
bool collided = collision(&char_rects[0], &char_rects[2]);

bool digonalMovement = 0;
if (character[player_nr].up && !character[player_nr].down) {
if (digonalMovement)
character[player_nr].y_vel = -SPEED * 0.86; //multiplying by sin(45)
else {
character[player_nr].y_vel = -SPEED;
}
digonalMovement = 1;
if (collided)
character[player_nr].y_vel -= 2 * character[player_nr].y_vel;
}
if (character[player_nr].down && !character[player_nr].up) {
if (digonalMovement)
character[player_nr].y_vel = SPEED * 0.86;
else {
character[player_nr].y_vel = SPEED;
}
digonalMovement = 1;
if (collided)
character[player_nr].y_vel -= 2 * character[player_nr].y_vel;
}
if (character[player_nr].left && !character[player_nr].right) {
if (digonalMovement)
character[player_nr].x_vel = -SPEED * 0.86;
else {
character[player_nr].x_vel = -SPEED;
}
digonalMovement = 1;
if (collided)
character[player_nr].y_vel -= 2 * character[player_nr].y_vel;
}
if (character[player_nr].right && !character[player_nr].left) {
if (digonalMovement)
character[player_nr].x_vel = SPEED * 0.86;
else {
character[player_nr].x_vel = SPEED;
}
digonalMovement = 1;
if (collided)
character[player_nr].y_vel -= 2 * character[player_nr].y_vel;
}
//clears diagonalMovement to make it false for next fram
digonalMovement = 0;

// update positions
character[player_nr].x_pos += character[player_nr].x_vel / 60;
character[player_nr].y_pos += character[player_nr].y_vel / 60;

// collision detection with bounds
if (character[player_nr].x_pos <= 0)
character[player_nr].x_pos = 0;
if (character[player_nr].y_pos <= 0)
character[player_nr].y_pos = 0;
if (character[player_nr].x_pos >= WINDOW_WIDTH - char_rects[player_nr].w)
character[player_nr].x_pos = WINDOW_WIDTH - char_rects[player_nr].w;
if (character[player_nr].y_pos >= WINDOW_HEIGHT - char_rects[player_nr].h)
character[player_nr].y_pos = WINDOW_HEIGHT - char_rects[player_nr].h;

// set the positions in the struct
char_rects[player_nr].y = (int)character[player_nr].y_pos;
char_rects[player_nr].x = (int)character[player_nr].x_pos;
}

最佳答案

player_movement_calc() 函数中,您有 collision(&char_rects[0], &char_rects[2])。看来您应该将玩家的矩形与

    bool collided = collision(&char_rects[0], &char_rects[1]);

您可能正在读取超出 char_rects 数组末尾的内容,从而导致未定义的行为。 printf 引起的任何副作用,例如为自己的目的分配内存或 stdout 缓冲区可能会改变程序的行为,例如通过使内存访问超出数组的末尾可读,因此消除了崩溃并隐藏了错误。

另一种可能的解释是,如果 collision 的结果未被使用且函数 collision 没有副作用,编译器可能会忽略对 collision 的调用。没有 staticprintf,该函数没有副作用(除了读取超出数组末尾而导致的崩溃之外,这无论如何都是未定义的行为)。更改 static 值可能被编译器认为是无用的,因为此变量未在任何地方使用且未定义 volatileprintf 有副作用,所以调用它会使 collision 不纯,因此不能省略调用。

总是很难尝试理解未定义的行为。调试时,您应该首先禁用所有优化。在禁用优化的 printf 的情况下,该错误可能是可见的,使用未优化的代码跟踪代码和观察局部变量应该容易得多。

一旦您在调试版本中出现可重现的崩溃错误,只需使用调试器向您展示它发生的位置。崩溃错误应该很容易调查。

关于使用无用的 printf 调用修复了条件返回值错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55619222/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com