Java - 像素完美碰撞 - 玩家和墙壁之间的间隙

Java - Pixel-Perfect Collision - gap between player and wall

我目前正在开发一款自上而下的射击游戏,但遇到了一些碰撞问题。 我的世界由瓷砖 (64x64) 组成。瓦片和实体是矩形。播放器以例如 2.74 的速度移动(为了更平滑的移动,不是以像素为单位)。但是当谈到玩家(一个实体)和一堵墙之间的碰撞时,我遇到了一些问题。为了检查是否发生碰撞,我采用玩家的当前位置和他的移动速度来计算他的下一个位置以及是否发生碰撞。但是我检查了途中的每个像素,所以即使移动速度很高我也不能跳过障碍物。假设玩家当前位置是 X:200 Y:200 并且他在 x 方向上每刻度移动 2.74 像素。我的游戏现在检查 X:201 Y:200、X:202 Y:200 或 X:202.74 Y:200 是否有任何碰撞,如果没有则移动玩家到那个位置。如果我现在尝试将播放器沿 x 方向进一步移动,并且有一堵墙距离 0.26 像素,播放器将不会移动并留下一个微小的间隙。我试图计算玩家和墙之间的距离,并将这个量添加到玩家的位置,但为此我需要知道玩家击中墙的哪一侧。此外,我希望玩家能够在他撞到的墙在他面前时上下移动,反之亦然。

这是我的碰撞方法(在Java):

public static boolean collision(float ex, float ey, int width, int height) { // ex, ey would be the next position of the player
    if (ex < 0 || ex + width > worldWidth || ey < 0 || ey + height > worldHeight) return true; // checks if this position is in the world
    int firstTileX = (int) (ex / Tile.TILE_SIZE); // calculates tiles he could possible collide width
    int firstTileY = (int) (ey / Tile.TILE_SIZE);
    int lastTileX = (int) ((ex + width - 1) / Tile.TILE_SIZE);
    int lastTileY = (int) ((ey + height - 1) / Tile.TILE_SIZE);
    for (int y = firstTileY; y <= lastTileY; y++) {
        if (y < 0) continue; // checks for out of bounds 
        if (y >= worldTileHeight) break;
        for (int x = firstTileX; x <= lastTileX; x++) {
            if (x < 0) continue;
            if (x >= worldTileWidth) break;
            if (tiles[y][x].solid) return true; // if the tile is solid -> collision found
        }
    }
    return false; // no collision found
}

还有我的运动方式:

public void move(float xa, float ya) {
    float nx, ny;
    while (xa != 0 || ya != 0) {
        nx = x;
        ny = y;
        if (xa != 0) {
            if (Math.abs(xa) > 1) { // if the x-speed is greater than 1
                nx = x + MathUtil.abs(xa); // returns -1 for negative numbers and 1 for positiv
                xa -= MathUtil.abs(xa);
            } else { // less than 1
                nx = x + xa;
                xa = 0;
            }
        }
        if (ya != 0) { // same here
            if (Math.abs(ya) > 1) {
                ny = y + MathUtil.abs(ya);
                ya -= MathUtil.abs(ya);
            } else {
                ny = y + ya;
                ya = 0;
            }
        }
        if (!Level.collision(nx, ny, width, height)) setPosition(nx, ny); // checks if there is an collision and sets the new position if not
        else if (!Level.collision(nx, y, width, height)) x = nx; // if there was a collision check if the player can walk in x direction
        else if (!Level.collision(x, ny, width, height)) y = ny; // or in y direction
    }
}

我的问题与 CoderMusgrove 在他 post (Pixel-perfect collision and doubles):

中的问题几乎相同

总结与问题

我有一个问题,如果一个实体的速度大于它进入的瓦片的距离,它会在它自己和瓦片之间至少留下一个像素,我真的不喜欢这样。我可以使用什么样的算法来找到实体和图块之间的最小差异?

如果您需要任何其他信息,我很乐意添加。

感谢您的帮助!

通过改变你的解释很容易解决。

您保留小数头寸是为了提高速度。为了碰撞检测和显示忽略分数(如果你要做亚像素渲染,在亚像素渲染精度级别上做碰撞)。

int screenX = (int) Math.round(objX);
int screenY = (int) Math.round(objY);
// rendering and collision detection based on rounded position