有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

基于java分片的碰撞检测,对象穿过分片

在较低的帧率下,我在基于平铺的级别上遇到了碰撞检测问题。我有一个用Java构建的平台游戏,带有LibGdx游戏引擎。在60帧速率下,游戏运行良好,但如果我尝试以每秒30帧的速度运行,当角色从跳下时,它会从瓦片中掉落

我发现这个角色动作太快了。我已经添加了一些内容来检查角色是否已经传递了任何平铺,请参见注释中的“//1”到“//1 end”。我不认为这真的有帮助,因为问题仍然存在

当角色撞到瓦片的角上时,从瓦片上掉下来似乎会发生,尽管我不确定这一点。它不会发生在平坦的地面上。下面是问题的图片(左边是错的,右边是应该的):

enter image description here

同样,这个问题只会在较低的帧率下发生。我不确定我必须在代码中更改什么。我的代码中缺少了什么?还是我必须使用不同的算法

以下是碰撞检测代码中最重要的部分。碰撞y检查y轴上的碰撞,碰撞x检查x轴上的碰撞。CheckTiles(checkX)有助于查找应检查的平铺(如果选中了x轴,则checkX为真;如果选中了假y轴,则checkX为假):

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};
}

共 (1) 个答案

  1. # 1 楼答案

    只有当A rect.overlaps(tile)true,B velocity.y > 0false时,才会运行“上面的检查是否平铺”代码。我怀疑在你关心的情况下,这段代码根本没有被执行。角色要么没有与平铺重叠,因此不会对上面的平铺进行检查,要么其速度不足以进行检查。然而,我并不完全理解速度是如何工作的(上下如何对应正负值?)我不熟悉这个游戏引擎

    不过,我会尝试另一种方法。与其先移动角色(我认为这是行rect.y += velocity.y;所做的),然后尝试检查它是否走得太远或穿过了一个磁贴,我会选择它移动的方向(velocity.y),然后寻找它会朝那边撞到的第一个磁贴。如果有,则将角色放置在该平铺上。如果在这个方向上velocity.y个单位没有任何阻碍,那么它就会在这个时间片中移动整个距离