Java - Pixel-Perfect Collision - 玩家和墙之间的差距

时间:2017-06-29 19:30:30

标签: java game-physics collision pixel-perfect

我目前正在制作一个自上而下的射手并且遇到一些碰撞问题。 我的世界是由瓷砖(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
    }
}

我的问题与他的帖子(Pixel-perfect collision and doubles)中的CoderMusgrove问题几乎相同:

摘要&amp;问题

我有一个问题,如果一个实体的速度比它进入的瓷砖的距离更大,它将至少在它自己和瓷砖之间留下一个像素,我真的不喜欢这个。我可以使用哪种算法来找到实体和磁贴之间最小的差异?

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

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

通过改变您的解释轻松解决。

为了达到细粒度的速度,您保留了一个小数位置。忽略分数以进行碰撞检测和显示(如果要进行子像素渲染,请在子像素渲染精度级别上进行碰撞)。

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