平台物理弹跳故障C++

Platforming physics bouncing glitch C++

本文关键字:故障 C++ 平台      更新时间:2023-10-16

我正在C++为一个简单的基于瓷砖的平台游戏实现一些非常基本的平台物理。我在这里(https://gamedev.stackexchange.com/questions/18302/2d-platformer-collisions)尽可能地遵循算法,但我仍然遇到一个奇怪的故障,玩家在瓷砖上反弹。我不太确定发生了什么。代码使用 SDL C++

void Player::update(vector< vector<Tile> > map) {
vector<Tile> collidingTiles;
x += xVel;
y += yVel;
boundingBox = Rect(x,y,16,16);
for(int iy=0;iy<MAPH;iy++) {
    for(int ix=0;ix<MAPW;ix++) {
        if (map[ix][iy].solid == true) {
            if (boundingBox.collide(map[ix][iy].boundingBox)) {
                collidingTiles.push_back(map[ix][iy]); // store all colliding tiles, will be used later
                Rect intersectingRect = map[ix][iy].boundingBox; // copy the intersecting rect
                float xOffset = x-intersectingRect.x; // calculate x-axis offset
                float yOffset = y-intersectingRect.y; //calculate y-axis offset
                if (abs(xOffset) < abs(yOffset)) {
                    x += xOffset;
                }
                else if (abs(xOffset) > abs(yOffset)) {
                    y += yOffset;
                }
                boundingBox = Rect(x,y,16,16); // reset bounding box
                yVel = 0;
            }
        }
    }
}
if (collidingTiles.size() == 0) {
    yVel += gravity;
}
};
if (abs(xOffset) < abs(yOffset)) {
    x += xOffset;
}
else if (abs(xOffset) > abs(yOffset)) {
    y += yOffset;
}
yVel = 0;

在此代码中,如果abs(xOffset) == abs(yOffset),则不会发生任何操作,这意味着玩家可以对角线进入实心图块。如果算法必须做出选择,删除第二个测试应该可以消除问题并修改y

另外,我想知道如果发生水平碰撞,您是否真的要重置垂直速度。这也意味着,如果碰撞是水平的,重力仍然应该适用(否则墙壁和天花板会很粘)。

int gravityApplies = true;//fix 2a
...
    if (abs(xOffset) < abs(yOffset)) {
        x += xOffset;
        xVel = 0;      //fix 2
    }
    else {             //fix 1
        y += yOffset;
        yVel = 0;      //fix 2
        if( yOfsset < 0 ){ // fix 2a
            gravityApplies = false;
        }
    }
 ...
 if (gravityApplies) { //fix 2a
     yVel += gravity;
 }

如果要进行弹性碰撞,请使用yVel = -yVel而不是yVel = 0(另一个方向类似)。您甚至可以在rest范围从 -10-0.8是一个不错的选择)的地方进行yVel = yVel * rest以获得半弹性碰撞。