播放器和磁贴之间的碰撞检测(2D)

时间:2022-01-18 08:56:54

I have been working on a 2D game, kind of like Terraria, and i have got to the stage where i am ready to do collision detection. I tried it myself, but it... well, its very strange. I was wondering if anybody could help me with this. I store all of my blocks in a 2D array:

我一直在研究2D游戏,有点像Terraria,我已经到了准备进行碰撞检测的阶段。我自己尝试过,但它......很奇怪。我想知道是否有人可以帮助我。我将所有块存储在2D数组中:

Block[][] map = new Block[mw][mh];

where mw is map width and mh is map height (in terms of number of blocks). Each Block is an image that is displayed as 16x16 pixels. Here is what i attempted, i know that it is wrong but i dont really know what i need to do.

其中mw是地图宽度,mh是地图高度(以块数表示)。每个块是一个显示为16x16像素的图像。这是我尝试的,我知道这是错的,但我真的不知道我需要做什么。

private void checkCollision() {

    for(int x = -1; x <= 1; x++){
        for(int y = -1; y <= 2; y++){
            Rectangle obj = new Rectangle((int)Block.getXOnScreen(xblock+x), (int)Block.getYOnScreen(yblock+y), 16, 16);
            try{
                if(main.map[(int) (xblock+x)][(int) (yblock+y)].solid && obj.intersects(bounds()){
                    if(y <= -1 && velY > 0){
                        velY = 0;
                        System.out.println("Collision below");
                        onground = true;
                    }else if(y >= 2 && velY < 0){
                        velY = 0;
                        System.out.println("Collision above");
                    }
                    if(x <= -1 && velX < 0){
                        velX = 0;
                        System.out.println("Collision left");
                    }else if(x >= 1 && velX > 0){
                        velX = 0;
                        System.out.println("Collision right");
                    }
                }
            }catch(Exception e){}
        }
    }
}

I call this method every tick like so, but it doesn't collide with anything so the player just falls.

我把这种方法称为每次滴答,但它不会与任何东西发生碰撞,所以玩家就会摔倒。

public void tick(){
    xblock += velX;
    yblock += velY;
    velY += gravity;

    checkCollision();
} 

If anyone knows how to do collision detection efficiently please can you share this with me. Thanks! :)

如果有人知道如何有效地进行碰撞检测,请与我分享。谢谢! :)

1 个解决方案

#1


-1  

Based on the few JavaFX/Swing applications that I once wrote, the way you want to detect collision is by always keeping track of where the object is, and when it moves check to see that it is new location (old + movement count) is not exceeding the limits of the map. If it does, you want to reset its position to be right on limit so that it can go in all other directions that are valid. If you keep trying to move outside of the limits then it should keep resetting your position.

基于我曾经写过的少数JavaFX / Swing应用程序,你想要检测碰撞的方式是始终跟踪对象的位置,以及何时移动检查以查看它是新位置(旧+移动计数)是不超过地图的限制。如果是这样,您希望将其位置重置为限制,以便它可以进入所有其他有效的方向。如果你继续试图超出极限,那么它应该继续重置你的位置。

So say the limit of the page is 500 pixels wide, you are in position 495, and each move is 10, next time you move you would in position 505, so that's clearly out of range. Thus you run a check if(currentPosition > limit) {reset position to limit} thus your currentPosition will be set to 500 which is right on the border, and within the limits.

所以说页面的极限是500像素宽,你在495位置,每次移动都是10,下次你移动时你会在505位置,所以这显然超出了范围。因此,您运行检查if(currentPosition> limit){reset position to limit},因此您的currentPosition将设置为500,它位于边界上且在限制范围内。

#1


-1  

Based on the few JavaFX/Swing applications that I once wrote, the way you want to detect collision is by always keeping track of where the object is, and when it moves check to see that it is new location (old + movement count) is not exceeding the limits of the map. If it does, you want to reset its position to be right on limit so that it can go in all other directions that are valid. If you keep trying to move outside of the limits then it should keep resetting your position.

基于我曾经写过的少数JavaFX / Swing应用程序,你想要检测碰撞的方式是始终跟踪对象的位置,以及何时移动检查以查看它是新位置(旧+移动计数)是不超过地图的限制。如果是这样,您希望将其位置重置为限制,以便它可以进入所有其他有效的方向。如果你继续试图超出极限,那么它应该继续重置你的位置。

So say the limit of the page is 500 pixels wide, you are in position 495, and each move is 10, next time you move you would in position 505, so that's clearly out of range. Thus you run a check if(currentPosition > limit) {reset position to limit} thus your currentPosition will be set to 500 which is right on the border, and within the limits.

所以说页面的极限是500像素宽,你在495位置,每次移动都是10,下次你移动时你会在505位置,所以这显然超出了范围。因此,您运行检查if(currentPosition> limit){reset position to limit},因此您的currentPosition将设置为500,它位于边界上且在限制范围内。