【问题标题】:Java Slick2d rectangle collision detection strange behaviorJava Slick2d矩形碰撞检测奇怪的行为
【发布时间】:2016-11-05 16:16:33
【问题描述】:

我想制作一个 slick2d java 游戏,但遇到了一个我在过去几个小时内无法解决的问题。我查看了许多其他帖子,但没有一个适合我的问题。

碰撞检测在 9/10 情况下工作正常。每次它与另一个矩形相交时,它都会根据下面的代码向后移动并显示在picture1 中。但有时,如果我尽可能靠近边缘,边缘似乎会重叠picture2。如果我上去,他会检测到交叉路口并向下移动。如果我下去,一切都很好。如果我向左或向右走,什么都不会发生。仅当矩形的角相交时才会发生这种情况。如果我同时上下左右,他有时会走错方向。似乎如果我同时向上和侧向,他会检测到碰撞并朝相反的方向移动,直到他到达与拐角相交的点并再次停止。关键是在检测和碰撞之后,他永远不会向后移动,而不是之前向前移动。此外,他不应该检测到矩形的交点并再次向后移动,但为什么他没有检测到边缘的交点,如图 2 所示?我真的希望有人知道为什么会这样。这个问题发生在各个方面。这是代码。

public class Player extends Creature {
int posX = 0;
int posY = 0;
Rectangle hitbox;
Input input;

public Player(Handler handler) {
    super(handler);
    // TODO Auto-generated constructor stub
}

@Override
public void init() {
    hitbox = new Rectangle(posX + 320, posY + 240, 32, 32);
}

@Override
public void render(Graphics g) {
    g.setColor(Color.red);
    g.draw(hitbox);

    g.setColor(Color.cyan);
    for (int i = 0; i < handler.getWorldCollision().size(); i++) {
        g.draw(handler.getWorldCollision().get(i));
    }

}

@Override
public void update(GameContainer gc, int delta) {
    input = gc.getInput();

    if (input.isKeyDown(Input.KEY_W)) {
        // move
        posY -= 100 * delta / 1000f;

        // if collision move back
        for (int i = 0; i < handler.getWorldCollision().size(); i++) {
            if (hitbox.intersects(handler.getWorldCollision().get(i))) {
                posY += 100 * delta / 1000f;
                break;
            }
        }
        hitbox.setY(posY + 240);
    }

    if (input.isKeyDown(Input.KEY_S)) {
        // move
        posY += 100 * delta / 1000f;

        // if collision move back
        for (int i = 0; i < handler.getWorldCollision().size(); i++) {
            if (hitbox.intersects(handler.getWorldCollision().get(i))) {
                posY -= 100 * delta / 1000f;
                break;
            }
        }
        hitbox.setY(posY + 240);
    }

    if (input.isKeyDown(Input.KEY_A)) {
        // move
        posX -= 100 * delta / 1000f;

        // if collision move back
        for (int i = 0; i < handler.getWorldCollision().size(); i++) {

            if (hitbox.intersects(handler.getWorldCollision().get(i))) {
                posX += 100 * delta / 1000f;
                break;
            }
        }
        hitbox.setX(posX + 320);
    }

    if (input.isKeyDown(Input.KEY_D)) {
        // move
        posX += 100 * delta / 1000f;

        // if collision move back
        for (int i = 0; i < handler.getWorldCollision().size(); i++) {

            if (hitbox.intersects(handler.getWorldCollision().get(i))) {
                posX -= 100 * delta / 1000f;
                break;
            }
        }
        hitbox.setX(posX + 320);
    }

    handler.setPlayerX(posX);
    handler.setPlayerY(posY);

}

}

handler.getWorldCollision() 是一个数组,其中包含图片中以青色绘制的所有矩形。

public class TestWorld extends World {

int[][] map = new int[87][35];
ArrayList<Rectangle> worldCollision;
MapLoader maploader;

public TestWorld(Handler handler) {
    super(handler);

}

@Override
public void init() throws IOException {
 maploader = new MapLoader(handler);
    map = maploader.readMapFile("gameResources/map/testmap.map");
    worldCollision = new ArrayList<Rectangle>();


}


@Override
public void render(Graphics g) throws SlickException {
    // Render all Tiles given by the map of this world.
    for (int i = 0; i < 87; i++) {
        for (int j = 0; j < 35; j++) {
                g.drawImage(handler.getTileList()[map[j][i]].getImage(), i * 16 - handler.getPlayerX(), j * 16 - handler.getPlayerY());
        }
    }
}

@Override
public void update(GameContainer gc, int delta) {
    worldCollision.clear();
    for (int i = 0; i < 87; i++) {
        for (int j = 0; j < 35; j++) {
        if(handler.getTileList()[map[j][i]].hasCollision()){
            worldCollision.add(new Rectangle(i * 16 - handler.getPlayerX(), j * 16 - handler.getPlayerY(), 16, 16));
        }               
        }
    }
    handler.setWorldCollision(worldCollision);
}

}

感谢您的建议!

【问题讨论】:

    标签: java collision-detection rectangles slick2d


    【解决方案1】:

    我不确定我是否完全明白为什么会发生这种重叠。你说“如果我尽可能靠近边缘,边缘似乎重叠”,所以向上时会发生重叠,但在向左或向右移动时不会更正?

    顺便说一下,如果左移或右移时没有检测到,那是因为您只在向上或向下移动时检查Y轴;虽然这应该足够了,但这就是为什么在左右移动并且已经与边缘重叠时没有纠正/检测到这一点的原因!

    【讨论】:

    • 对!一般来说,在向左或向右移动时应该不需要检查 Y 碰撞,因为这应该已经完成​​了。
    • 在 Y 碰撞检测“起作用”之前我可以上升的最远点,让我回到原点,如上图 2 所示。但是,如果我停留在边缘似乎重叠的这一点上,就会出现问题。如果我的 32x32 玩家碰撞箱与两个 16x16 方块碰撞箱完全匹配,我将无法左右移动。如果它们不完全匹配,我可以向左或向右但在“反转”方向,直到玩家碰撞箱移动到它与两个瓷砖碰撞箱完全匹配并再次停止的点。
    • 我猜当它匹配两个青色矩形时它会被阻止,因为你尝试向左移动(例如)它检测到你正在与下一个青色矩形相交,因此你取消了这个移动:你没有移动,你被挡住了。还有关于方向反转,仍在查看您的代码
    • 这是有道理的。我添加了世界级,其中包含生成的瓦片命中框以供进一步深入
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多