Java 如何使用多面墙(迷宫)进行碰撞检测?

Java 如何使用多面墙(迷宫)进行碰撞检测?,java,collision-detection,maze,Java,Collision Detection,Maze,在我的游戏中,玩家在迷宫中导航。我不知道如何正确地检测墙壁的碰撞。停留在某个区域内很容易进行碰撞检测: if (x > rightWallX - playerWidth) x = rightWallX - playerWidth; if (x < leftWallX) x = leftWallX; //... if(x>rightWallX-playerWidth)x=rightWallX-playerWidth; 如果(x0&&!ublock){ dy+=-速度; }else i

在我的游戏中,玩家在迷宫中导航。我不知道如何正确地检测墙壁的碰撞。停留在某个区域内很容易进行碰撞检测:

if (x > rightWallX - playerWidth) x = rightWallX - playerWidth;
if (x < leftWallX) x = leftWallX;
//...
if(x>rightWallX-playerWidth)x=rightWallX-playerWidth;
如果(x
但是如何对许多墙进行碰撞检测呢


我可以进行简单的碰撞检测而无需进行校正(如
如果(相交)返回true;
),但我无法正确地进行校正。如果我只是存储旧的
x
y
并重置它们,那么

  • 该对象从未实际接触过墙
  • 如果物体可以上升,但被阻挡在右边,它不会上升,只是不会移动

  • 迷宫中的碰撞检测是如何完成的?

    解决碰撞检测后,修复碰撞的最简单方法是将参与者移动到距离其碰撞对象最近的有效位置。这假设没有惯性,但对于迷宫式游戏或自上而下的地图爬行游戏来说已经足够了

    如果您想进一步简化计算,可以将自己限制在检测更改参与者的
    x
    y
    坐标是否更好。如果您的演员有一个轴对齐的矩形命中框,并且所有障碍物也都是轴对齐的矩形(最简单的情况),那么这个假设确实是正确的。然而,在其他一些情况下,结果可能并不令人满意(潜在的伪影:滑动斜壁的速度提升-在大多数迷宫游戏中并非如此)


    请记住,多重碰撞可能同时发生(推到两堵墙上)。如果两堵墙之间没有尖锐的角度,演员双方都可以相交(比如说,如果所有障碍物都是轴线对齐且间距足够大的话),那么依次修复每次碰撞就足够了——只是在第一次碰撞后不要停止。

    好的,所以我目前正在制作一个2D自顶向下视图游戏,我不确定你是如何创建迷宫的。但是,在我的游戏中,我的关卡是从一个平铺[][]平铺=新的平铺[levelWidth][levelHeight]创建的;数组。我处理碰撞检测的方法是检查周围的瓷砖是否牢固

    这是我的getTile方法

    public Tile[][] getTile(int x, int y) {
        if (x < 0 || x >= getWidth() || y < 0 || y >= getHeight()) {
        return new VoidTile();
    } else {
        return tiles[x][y];
    }
    }
    
    然后在我的播放器更新方法中

    public void tick() {
        float dx = 0;
        float dy = 0;
    
        if (input.up.isPressed()) {
            direction = 0;
        } else if (input.down.isPressed()) {
            direction = 2;
        } else if (input.left.isPressed()) {
            direction = 3;
        } else if (input.right.isPressed()) {
            direction = 1;
        } else {
            direction = 4; // standing
        }
    
        checkBlockedDirection((int)x, (int)y);
    
    
        if (input.up.isPressed() && y > 0 && !uBlocked) {
                dy += -speed;
        } else if (input.down.isPressed() && y < map.getHeight() - 1 && !dBlocked) {
                dy += speed;
        } else if (input.left.isPressed() && x > 0 && !lBlocked) {
                dx += -speed;
        } else if (input.right.isPressed() && x < map.getWidth() - 1 && !rBlocked) {
                dx += speed;
        }
        x += dx;
        y += dy;
    
    }
    
    public void tick(){
    浮点数dx=0;
    浮动dy=0;
    if(input.up.isPressed()){
    方向=0;
    }else if(input.down.isPressed()){
    方向=2;
    }else if(input.left.isPressed()){
    方向=3;
    }else if(input.right.isPressed()){
    方向=1;
    }否则{
    方向=4;//站立
    }
    选中BlockedDirection((int)x,(int)y);
    if(input.up.isPressed()&&y>0&&!ublock){
    dy+=-速度;
    }else if(input.down.isPressed()&&y0&&!lblock){
    dx+=-速度;
    }else if(input.right.isPressed()&&x
    基本上,它只是检查上、下、左或右的块是否是实心的。如果它们是实心的,那么它不会移动;如果它们不是实心的,那么你可以朝着所需的方向移动

    不确定这是否有帮助,但这只是我对这种网格冲突检测的看法:)

    希望这有帮助:)


    享受

    您可以使用Rectangle.intersects()方法:


    新矩形(0,0100,50)只是一个示例,您可以对其进行更改。

    “我可以在不进行更正的情况下执行普通碰撞检测”这是一个好主意;现在添加更正。“存储旧的x和y并重置它们”来吧,你可以做得更好:-)JanDvorak我还能做什么?我想不出任何其他方法:/Suggestion#1:在大多数情况下,只需重置
    x
    y
    @JanDvorak,就足够了,但物体实际上从未接触过墙壁,它在几像素之外徘徊。(这是因为对象不只是每刻度移动1个像素)建议#2:不需要重置该值。只要改变它就足够了。
    public void tick() {
        float dx = 0;
        float dy = 0;
    
        if (input.up.isPressed()) {
            direction = 0;
        } else if (input.down.isPressed()) {
            direction = 2;
        } else if (input.left.isPressed()) {
            direction = 3;
        } else if (input.right.isPressed()) {
            direction = 1;
        } else {
            direction = 4; // standing
        }
    
        checkBlockedDirection((int)x, (int)y);
    
    
        if (input.up.isPressed() && y > 0 && !uBlocked) {
                dy += -speed;
        } else if (input.down.isPressed() && y < map.getHeight() - 1 && !dBlocked) {
                dy += speed;
        } else if (input.left.isPressed() && x > 0 && !lBlocked) {
                dx += -speed;
        } else if (input.right.isPressed() && x < map.getWidth() - 1 && !rBlocked) {
                dx += speed;
        }
        x += dx;
        y += dy;
    
    }
    
        public Rectangle Player(){
             return new Rectangle(PlayerX,PlayerY,PlayerWidth,PlayerHeight);
             //we do this for getting players x and y values every tick
        }
    
        if(Player().intersects(new Rectangle(0,0,100,50)))//if(player touching wall)