【发布时间】:2014-03-05 05:58:39
【问题描述】:
我在以较低帧速率在基于图块的级别上进行碰撞检测时遇到问题。我有一个带有 LibGdx 游戏引擎的 Java 平台游戏。在 60 帧速率下,游戏运行良好,但如果我尝试以 30 FPS 的速度运行,角色从跳跃中落下时会穿过瓷砖。
我发现角色移动得太快了。我已经添加了一些东西来检查角色是否已经通过了任何瓷砖,请参阅 cmets 中的“// 1”到“// 1 end”。我不认为它真的有帮助,因为问题仍然存在。
当角色撞到瓷砖的角落时,似乎会从瓷砖上掉下来,虽然我不确定。它不会发生在平坦的地面上。这是问题的图片(左边是错误的,右边是应该的):
同样,问题只发生在较低的帧速率下。我不确定我必须在我的代码中更改什么。我的代码中缺少什么?还是我必须使用不同的算法?
这里是碰撞检测代码中最重要的部分。 collisionY 检查 y 轴上的碰撞,collisionX 在 x 轴上。 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};
}
【问题讨论】:
-
你从不使用增量值吗?它可以通过调用 Gdx.app.getDeltaTime() 来获得。此增量时间是一个浮点值,表示最后一帧渲染所花费的时间。这样,您可以确保实体的速度从一个系统到另一个系统是恒定的,而不是让速度快的计算机具有优势。
-
是的,我使用它。不同FPS下速度是一样的。
标签: java libgdx collision-detection game-physics frame-rate