多边形碰撞(有时)不起作用,可能是浮动错误

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();

你需要明确。如果碰撞发生在左侧,则需要迫使球向右移动,反之亦然。这样,由于浮点误差,如果您测量同一面墙的两次碰撞,您的球仍会反弹到正确的一侧。