c - 用无用的 printf 调用修复了条件返回值错误
问题描述
我试图为我的简单游戏(学校项目)编写一个简单的碰撞检测函数,直到我添加了一个无意义的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;
}
编辑:我使用了静态布尔,因为我试图让 Visual Studio 在监视窗口中显示布尔变量的值,即使它(变量)超出范围,它也不起作用,我忘了删除静态。但是,无论我是否使用静态,问题都存在。
编辑 2:这是调用上述函数的函数(我知道 digonalMovement 需要一个小修复,以使对角线移动时两个方向的速度变慢(目前只有其中一个变慢),但这不应该有什么解决手头的问题):
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
没有副作用,编译器可能会省略调用。没有static
和printf
,该函数没有副作用(除了由于读取超出数组末尾而导致的崩溃,这无论如何都是未定义的行为)。编译器可能会认为更改该static
值是无用的,因为该变量未在任何地方使用且未定义volatile
。printf
有副作用,所以调用它会变得collision
不纯,因此不能省略调用。
尝试理解未定义的行为总是很困难的。调试时,应首先禁用所有优化。如果没有禁用优化,该错误可能是可见的printf
,并且使用未优化的代码跟踪代码和观察局部变量应该更容易。
一旦在调试版本中出现可重现的崩溃错误,只需使用调试器向您展示它发生的位置。崩溃错误应该很容易调查。
推荐阅读
- r - 谷歌云服务器虚拟机可以通过 SSH 访问我的本地机器吗?
- python - Django 反向正则表达式匹配
- avaloniaui - Avalonia UI,通过绘制事物创建自定义控件
- java - OneToMany 双向关系不在子实体中插入外键
- python - 有没有办法获得 tkinter 正方形的颜色?
- gradle - 从脚本返回的 Gradle 导出环境
- python - 为什么 jQuery 支持的注册按钮没有响应?
- android-constraintlayout - android constraintlayout,椭圆不能按预期工作
- r - read.csv 在 R 中将列名向右移动
- javascript - ReactJS动态更改背景图像不起作用