[英]Tile based collision detection, object falls through tiles
我在较低帧速率下基于图块的级别上的碰撞检测遇到问题。 我有一个使用LibGdx游戏引擎在Java中构建的平台游戏。 以60的帧速率运行时,游戏运行良好,但如果尝试以30 FPS的速度运行,则角色从跳跃中掉落时会掉落在瓷砖上。
我发现角色移动得太快了。 我已经添加了一些东西来检查角色是否已经传递了任何切片,请参见注释中的“ // 1”到“ // 1 end”。 我认为这真的没有帮助,因为问题仍然存在。
尽管我不确定,但当角色碰到瓷砖的角落时,似乎会掉落瓷砖。 它不会在平坦的地面上发生。 这是问题的图片(左边是错误的,右边是应该的样子):
同样,该问题仅在较低的帧率下发生。 我不确定我必须在代码中进行哪些更改。 我的代码中缺少什么? 还是我必须使用其他算法?
这是冲突检测代码中最重要的部分。 碰撞Y检查y轴上的碰撞,碰撞X检查x轴上的碰撞。 CheckTiles(checkX)帮助查找应检查的图块(如果选中了x轴,则选中了true,如果选中了y轴,则checkX为true):
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};
}
只有在A) rect.overlaps(tile)
为true
且B) velocity.y > 0
为false
true
,才会运行“检查上方的图块”代码。 我怀疑在您关心的情况下,此代码根本没有被执行。 角色不是与图块重叠,因此不会对上方的图块进行检查,或者角色的速度不会使检查发生。 但是,我不完全了解速度的工作原理(上下如何对应正值和负值?),我对这个游戏引擎并不熟悉。
不过,我会尝试另一种方法。 与其先移动角色(我认为这是rect.y += velocity.y;
所做的rect.y += velocity.y;
),然后尝试检查它是否走得太远或穿过瓷砖,我不如选择一个方向它正在移动( velocity.y
),并寻找它将以这种方式撞击的第一个图块 。 如果有一个,则将角色放在该图块上。 如果在该方向上没有velocity.y
单位的方式,则它将在此时间段内移动整个距离。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.