多边形碰撞(有时)不起作用,可能是浮动错误
Polygon collision (sometimes) not working, possibly float error
我正在用 C++ 编写程序,使用 OpenGL 绘制元素。这是一个简单的 2D 游戏,其中一个正方形一旦撞到其中一堵墙,即屏幕的边界,就应该改变它的方向。为了设置边界框,我制作了横跨边长的小方块。我的坐标系各个方向都是从-1到1。
有时一切正常,但最终移动的方块会超出 window。似乎我的程序识别出碰撞,但仍然没有阻止它越过界限。这是我的碰撞检查:
bool checkCollisionRectRect(Rectangle* p1, Rectangle* p2) {
float eps = 0.005;
RectHitbox* rect1 = (RectHitbox*)p1->getHitbox();
RectHitbox* rect2 = (RectHitbox*)p2->getHitbox();
if (rect1->x < rect2->x + rect2->w + eps &&
rect1->x + rect1->w + eps > rect2->x &&
rect1->y < rect2->y + rect2->h + eps &&
rect1->h + rect1->y + eps > rect2->y) {
return true;
}
return false;
}
这是目前为每一帧检查碰撞的方式:
void Game::handleBallWallCollision() {
bool collisionX = checkCollision(this->ball, this->boundBoxes->at(0)) ||
checkCollision(this->ball, this->boundBoxes->at(1));
bool collisionY = checkCollision(this->ball, this->boundBoxes->at(2)) ||
checkCollision(this->ball, this->boundBoxes->at(3));
if (collisionX) { // Collision X
ball->flipDirectionX();
} else if (collisionY) { // Collision Y
ball->flipDirectionY();
}
}
为了避免出现浮点数错误,我添加了eps值。我仍然不知道出了什么问题,也不知道为什么广场有时会越过界限。有没有人以前遇到过这个问题,并可能通过一些巧妙的方法解决了?
您不需要 epsilon。其实就是错误的根源。
if (collisionX) { // Collision X
ball->flipDirectionX();
当球移动得足够慢时,一旦进入 epsilon 区域,它就会每一帧左右弹跳。
但仅删除 epsilon 不足以解决问题。您需要的是:
if (collisionXLeftSide) { // Collision X on the left
ball->goRight();
你需要明确。如果碰撞发生在左侧,则需要迫使球向右移动,反之亦然。这样,由于浮点误差,如果您测量同一面墙的两次碰撞,您的球仍会反弹到正确的一侧。
我正在用 C++ 编写程序,使用 OpenGL 绘制元素。这是一个简单的 2D 游戏,其中一个正方形一旦撞到其中一堵墙,即屏幕的边界,就应该改变它的方向。为了设置边界框,我制作了横跨边长的小方块。我的坐标系各个方向都是从-1到1。
有时一切正常,但最终移动的方块会超出 window。似乎我的程序识别出碰撞,但仍然没有阻止它越过界限。这是我的碰撞检查:
bool checkCollisionRectRect(Rectangle* p1, Rectangle* p2) {
float eps = 0.005;
RectHitbox* rect1 = (RectHitbox*)p1->getHitbox();
RectHitbox* rect2 = (RectHitbox*)p2->getHitbox();
if (rect1->x < rect2->x + rect2->w + eps &&
rect1->x + rect1->w + eps > rect2->x &&
rect1->y < rect2->y + rect2->h + eps &&
rect1->h + rect1->y + eps > rect2->y) {
return true;
}
return false;
}
这是目前为每一帧检查碰撞的方式:
void Game::handleBallWallCollision() {
bool collisionX = checkCollision(this->ball, this->boundBoxes->at(0)) ||
checkCollision(this->ball, this->boundBoxes->at(1));
bool collisionY = checkCollision(this->ball, this->boundBoxes->at(2)) ||
checkCollision(this->ball, this->boundBoxes->at(3));
if (collisionX) { // Collision X
ball->flipDirectionX();
} else if (collisionY) { // Collision Y
ball->flipDirectionY();
}
}
为了避免出现浮点数错误,我添加了eps值。我仍然不知道出了什么问题,也不知道为什么广场有时会越过界限。有没有人以前遇到过这个问题,并可能通过一些巧妙的方法解决了?
您不需要 epsilon。其实就是错误的根源。
if (collisionX) { // Collision X
ball->flipDirectionX();
当球移动得足够慢时,一旦进入 epsilon 区域,它就会每一帧左右弹跳。
但仅删除 epsilon 不足以解决问题。您需要的是:
if (collisionXLeftSide) { // Collision X on the left
ball->goRight();
你需要明确。如果碰撞发生在左侧,则需要迫使球向右移动,反之亦然。这样,由于浮点误差,如果您测量同一面墙的两次碰撞,您的球仍会反弹到正确的一侧。