我试着为我的简单游戏(学校项目)编写一个简单的碰撞检测函数,直到我添加了一个无意义的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;
}
编辑:
我使用静态bool是因为我试图让Visual studio在监视窗口中显示布尔变量的值,即使它(变量)不在作用域内,它也不起作用,我忘记删除static。但问题是我是否使用static。
编辑2:
下面是调用上述函数的函数(我知道在对角线方向移动时,需要一个小的修正,以使速度在两个方向上都变慢(目前只有一个方向变慢),但这与手头的问题没有任何关系):
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
,这个bug可能是可见的,如果没有优化的代码,跟踪代码和监视局部变量应该会容易得多。一旦在调试生成中出现可复制的崩溃错误,只需使用调试器向您显示错误发生的位置。崩溃错误应该很容易调查。
关于c - 通过无用的printf调用修复了条件返回值错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55619222/