使用Slick检测2D环境中的碰撞

时间:2014-09-06 03:57:55

标签: java 2d collision slick2d

我在游戏中检测到碰撞时遇到了一些麻烦。似乎碰撞检测仅部分时间仅在一些墙壁上起作用。我正在为我的库使用slick2d。如果您需要更多代码或信息,我可以提供给您。我现在必须到某个地方,所以我只是快速输入,但如果你需要更多东西,请问。

代码:

@Override
public void manageWallCollision(Scene currScene) {
    for(int i = 0; i < currScene.getMapManager().getWalls().size(); i++){
    MapTile currTile = currScene.getMapManager().getWalls().get(i);

        if(currTile.isCollidable()){
            if(this.getBounds().intersects(currTile.getBounds())){
                //bottom
                if(this.y2 < currTile.getY()){

                }
                //right
                else if(this.x2 < currTile.getX()){

                }
                //left
                else if(this.y > currTile.getY2()){

                }
                //top
                else if(this.x > currTile.getX()){

                }
                break;
            }
        }
    }
}

感谢任何帮助。感谢。

新守则:

    for(int i = 0; i < currScene.getMapManager().getWalls().size(); i++){
        MapTile currTile = currScene.getMapManager().getWalls().get(i);

        if(currTile.isCollidable()){
            if(this.getBounds().intersects(currTile.getBounds())){
                //down
                if(this.y2 < currTile.getY() && this.y < currTile.getY2() && this.y2 < currTile.getY2()){
                    this.setY(currTile.getY() - this.getHEIGHT());
                }
                //up
                if(this.y < currTile.getY2() && this.y2 > currTile.getY() && this.y2 > currTile.getY2()){
                    this.setY(currTile.getY2());
                }
                //right
                if(this.x2 < currTile.getX() && this.x < currTile.getX2() && this.x2 < currTile.getX2()){
                    this.setX(currTile.getX() - this.getWIDTH());
                }
                //left
                if(this.x < currTile.getX2() && this.x2 > currTile.getX() && this.x2 > currTile.getX2()){
                    this.setX(currTile.getX2());
                }

            }
        }
    }

我仍有问题。它可以很好地检测碰撞,但无论它撞到特定的墙壁上,它都会到达同一个地方。想象一下2d房间。因此,如果它与左墙碰撞,那么它会自动进入该墙上的位置。如果你试着沿着墙壁滑动那么它就会变得非常微不足道,而你却不断前进然后向后移动。我对发生的事感到困惑。

1 个答案:

答案 0 :(得分:2)

Slick2d中的碰撞检测实际上比人们首先想到的要困难得多。首先,在矩形中引用X和Y点的标准方法如下:X1是矩形中包含的最小 X值,X2是最大。 Y也是如此(记住最小的Y值位于矩形的顶部)。

您的代码无法解释,原因如下:

    if(currTile.isCollidable()){
        if(this.getBounds().intersects(currTile.getBounds())){
            if(this.y2 < currTile.getY()){

                 /*This will only return true as long as 
                 the player intersects the tile and his greatest
                 Y value is less than the smallest Y value of the box.

                 This is not actually possible if you think about it as
                 the greatest Y value must in some way be contained by the
                 box for a bottom side collision.*/

            } else if(this.x2 < currTile.getX()){

                 /*The same can be said for all of your other conditionals.
                 As in, all of your conditionals CANNOT be true if the boxes
                 intersect and therefore your collision code will not work.*/

            } else if(this.y > currTile.getY2()){

            } else if(this.x > currTile.getX()){

            }
            break;
        }
    }
总而言之,尝试开发一种快速/高效的像素完美碰撞系统几乎是不可能的(我已多次尝试和失败)。这是一个有效的例子;但是,你必须添加一些我将解释的额外代码。此外,这是一个必须添加到MapTile类并从更新方法调用的检查:

public void checkCollision(Scene s) {
     //Down
     if (s.player.getMaxY() > this.getMinY() && 
                s.player.getMinY() < this.getMinY() && 
                s.player.x + s.player.width > this.x && s.player.x < this.getMaxX()) {

            s.player.y = this.y - s.player.height;

            /*Checks to see if the player intersects moving downwards. If the 
            player is colliding the code moves the player to look as if it stopped
            perfectly rather than moving slightly inside of the wall*/

     //Up
     } else if (s.player.getMinY() < this.getMaxY() && 
                s.player.getMaxY() > this.getMaxY() && 
                s.player.x + s.player.width > this.x && s.player.x < this.getMaxX()) {

            s.player.y = this.y + this.height;

     //Left
     } else if (s.player.getMinX() < this.getMaxX() && 
                s.player.getMaxX() > this.getMaxX() && 
                s.player.intersects(this)) {

            s.player.x = this.x + this.width;

     //Right
     } else if (s.player.getMaxX() < this.getMinX() && 
                s.player.getMinX() > this.getMinX() && 
                s.player.intersects(this)) {

            s.player.x = this.x - s.player.width;               

     }
}

我已经使用Slick2d制作了几年的游戏,到目前为止,这是我发现做事的最好方法。 s.player代表游戏的主角,代表棋子。希望这会有所帮助:)