1

我目前正在开发 Top-Down-Shooter 并且遇到一些碰撞问题。我的世界是由瓷砖(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 在他的帖子中的问题(像素完美碰撞和双打)几乎相同:

总结与问题

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

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

谢谢你的帮助!

4

1 回答 1

0

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

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

int screenX = (int) Math.round(objX);
int screenY = (int) Math.round(objY);
// rendering and collision detection based on rounded position
于 2017-06-29T20:08:26.307 回答