我目前正在开发一个自上而下的Shooter,并且遇到了一些碰撞问题。我的世界是由瓦片(64x64)组成的。平铺和实体都是矩形。玩家以例如2.74的速度移动(并且为了更平滑的移动而不以像素为单位)。但是当涉及到玩家(一个实体)和一面墙之间的碰撞时,我有一些问题。为了检查是否有碰撞,我用我的球员的当前位置和他的移动速度来计算他的下一个位置,以及是否有任何碰撞。但是我检查了路上的每个像素,所以即使移动速度很快,我也不能跳过障碍物。假设玩家的当前位置是X:200 Y:200,他在x方向上移动了2.74个像素。我的游戏现在检查在X:201Y:200,X:202Y: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在他的帖子(Pixel-perfect collision and doubles)中的问题基本相同:
摘要和问题
我有一个问题,如果一个实体的速度大于它要进入的瓦片的距离,它会在它自己和瓦片之间留下至少一个像素,我真的不喜欢这样。我可以使用哪种算法来找到实体和磁贴之间的最小差异?
如果您需要任何其他信息,我很乐意补充。
谢谢你的帮忙!
发布于 2017-06-30 04:08:26
很容易通过改变你的解释来解决。
为了获得细粒度的速度,您将保留一个小数位置。出于碰撞检测和显示的目的而忽略分数(如果要进行子像素渲染,请在子像素渲染精度级别上进行碰撞)。
int screenX = (int) Math.round(objX);
int screenY = (int) Math.round(objY);
// rendering and collision detection based on rounded position
https://stackoverflow.com/questions/44833505
复制相似问题