我在较低帧率的基于图块的级别上遇到碰撞检测问题。我有一个用Java构建的平台游戏和LibGdx游戏引擎。在60的帧速率下,游戏运行良好,但是如果我尝试30 FPS,当角色从跳跃状态下降时,角色将会掉落。
我发现角色移动得太快了。我已经添加了一些内容来检查角色是否已经传递过任何切片,请在评论中看到“// 1”到“// 1 end”。我不认为这确实有帮助,因为问题仍然存在。
当角色碰到瓷砖的角落时,似乎会发生掉落在瓷砖上,虽然我不确定。它不会发生在平坦的地面上。这是一个问题的图片(左边是错的,它应该是怎么回事):
同样,问题只发生在较低的帧速率下。我不确定我的代码中需要更改什么。我的代码中缺少什么?或者我必须使用不同的算法吗?
以下是碰撞检测代码中最重要的部分。 collisionY检查y轴上的碰撞,x轴上的collisionX。 CheckTiles(checkX)有助于找到应该检查的切片(如果选中了x轴,则checkX为真,如果选中了错误的y轴):
protected boolean collisionY(Rectangle rect) {
int[] bounds = checkTiles(false);
Array<Rectangle> tiles = world.getTiles(bounds[0], bounds[1], bounds[2], bounds[3]);
rect.y += velocity.y;
if(velocity.y < 0 ) {
grounded = false;
}
for (Rectangle tile : tiles) {
if (rect.overlaps(tile)) {
if (velocity.y > 0) {
this.setY(tile.y - this.getHeight());
}
else {
// 1 Check if there are tiles above
Rectangle r = null;
int i = 1;
Rectangle r1 = null;
do {
r1 = r;
r = world.getTile(tile.x, tile.y + i);
i++;
} while (r != null);
if(r1 != null) {
this.setY(r1.y + r1.height);
}
// 1 end
else {
this.setY(tile.y + tile.height);
}
hitGround();
}
return true;
}
}
}
protected boolean collisionX(Rectangle rect) {
int[] bounds = checkTiles(true);
Array<Rectangle> tiles = world.getTiles(bounds[0], bounds[1], bounds[2], bounds[3]);
rect.x += velocity.x;
for (Rectangle tile : tiles) {
if (rect.overlaps(tile)) {
return true;
}
}
return false;
}
protected int[] checkTiles(boolean checkX) {
int startX, startY, endX, endY;
if(checkX) {
if (velocity.x > 0) {
startX = endX = (int) (this.getX() + this.getWidth() + velocity.x);
}
else {
startX = endX = (int) (this.getX() + velocity.x);
}
startY = (int) (this.getY());
endY = (int) (this.getY() + this.getHeight());
}
else {
if (velocity.y > 0) {
startY = endY = (int) (this.getY() + this.getHeight() + velocity.y); //
}
else {
startY = endY = (int) (this.getY() + velocity.y);
}
startX = (int) (this.getX());
endX = (int) (this.getX() + this.getWidth());
}
return new int[]{startX, startY, endX, endY};
}
答案 0 :(得分:2)
仅当A)rect.overlaps(tile)
为true
且B)velocity.y > 0
为false
时,才会运行“检查上方是否为瓷砖”代码。我怀疑在你关心的情况下,这段代码根本没有被执行。字符要么不与图块重叠,所以不会检查上面的图块,或者它的速度不会发生检查。但是,我不完全理解速度是如何工作的(上下如何对应于正值和负值?)并且我不熟悉这个游戏引擎。
rect.y += velocity.y;
所做的那样),然后尝试检查它是否已经走得太远或通过一个瓦片,我会采取它移动的方向({ {1}})并查找它会以那种方式点击的第一个图块。如果有,则将该字符放在该图块上。如果在该方向上velocity.y
单位没有任何方法,那么它将在此时间片中移动整个距离。