简体   繁体   English

java 2d 平台游戏碰撞错误

[英]java 2d platformer collision bug

When the character walks in to a wall they can't go through but when jumping in to a wall, the player is teleported up or down depending on how high you hit the tile.当角色走入墙壁时,他们无法通过 go 但是当跳入墙壁时,玩家会根据您击中瓷砖的高度被向上或向下传送。

How can i make so that the player just falls when they hit a wall?我怎样才能让玩家在撞墙时摔倒?

The movement and collision detection happens in Player.java.移动和碰撞检测发生在 Player.java 中。

I think it has to do with checkin if the player is standing on a block (the first check in the for loop) but im not sure.我认为如果玩家站在一个块上(for循环中的第一次检查),这与签入有关,但我不确定。

link to the files on github链接到 github 上的文件

a visual representation of my problem我的问题的直观表示

This is how i check for collision:这就是我检查碰撞的方式:

public void collisionCheck(){
    for (ArrayList<Integer> tile: Game.tileCoordinates){
        //current row of the player
        int row = y / Game.TILE_SIZE;
        // the row below the player
        int rowBelow = y / Game.TILE_SIZE + 1;
        // the column the left of the player is in
        int columnLeft = x / Game.TILE_SIZE;
        // the column the right of the player is in
        int columnRight = (x + width) / Game.TILE_SIZE;

        // check if the player goes through the block below
        if (tile.get(1) / Game.TILE_SIZE == rowBelow){
            if ((tile.get(0) / Game.TILE_SIZE == columnLeft || 
                 tile.get(0) / Game.TILE_SIZE == columnRight)) {
                y = tile.get(1) - height;
                if (jumping) {
                    jumping = false;
                    Game.spacePressed = false;
                    dustAfterShowed = false;
                    xAfterJump = x;
                    yAfterJump = y;
                }
                if (falling){
                    falling = false;
                }
            }
        }

        // check if the player goes through the side of a block
        if (y <= tile.get(1) && y + height <= tile.get(1) + Game.TILE_SIZE &&
               y + height >= tile.get(1) && row == tile.get(1) / Game.TILE_SIZE) {
            // left side
            if (x + width >= tile.get(0) && x <= tile.get(0)) {
                x = tile.get(0) - width;
            }
            // right side
            if (x + width >= tile.get(0) + Game.TILE_SIZE && 
                    x <= tile.get(0) + Game.TILE_SIZE) {
                x = tile.get(0) + Game.TILE_SIZE;
            }
        }
        // check if the player hits a block from below
        if (tile.get(1) / Game.TILE_SIZE == row && 
               (tile.get(0) / Game.TILE_SIZE == columnLeft ||
                tile.get(0) / Game.TILE_SIZE == columnRight)){
            if (jumping) {
                y = tile.get(1) + Game.TILE_SIZE;
                velocity = 0;
            }
        }
    }

I fixed it by addig a few booleans, when the player hits a wall from the side, it now doesn't check for bottom tile collision anymore (making the player fall instead of stay mid air).我通过添加一些布尔值来修复它,当玩家从侧面撞到墙壁时,它现在不再检查底部瓷砖碰撞(使玩家跌倒而不是停留在半空中)。

When checking for top tile collision, you check in advance.检查顶部瓷砖碰撞时,请提前检查。 if you dont check in advance it will detect side collision because the top left and right pixel are in the tile.如果您不提前检查,它会检测到侧面碰撞,因为左上角和右上角的像素都在图块中。

    for (ArrayList<Integer> tile: Game.tileCoordinates){
        sideCollision = false;
        blockRight = false;
        blockLeft = false;

        // check for side collision, if colided then disable movement
        if ((y / Game.TILE_SIZE == tile.get(1) / Game.TILE_SIZE) &&
                (x < tile.get(0) && x + width > tile.get(0) &&
                 x + width < tile.get(0) + Game.TILE_SIZE)) {
            sideCollision = true;
            blockRight = true;
            x = tile.get(0) - width - 1;
        }

        if ((y / Game.TILE_SIZE == tile.get(1) / Game.TILE_SIZE) &&
                (x < tile.get(0) + Game.TILE_SIZE && x > tile.get(0) &&
                 x + width > tile.get(0) + Game.TILE_SIZE)) {
            sideCollision = true;
            blockLeft = true;
            x = tile.get(0) + Game.TILE_SIZE + 1;
        }

        // if player is about to hit head, stop upwards movement
        if ((y - velocity <= tile.get(1) + Game.TILE_SIZE &&
                 y - velocity > tile.get(1)) && ((x >= tile.get(0) &&
                 x <= tile.get(0) + Game.TILE_SIZE) ||
                (x + width >= tile.get(0) &&
                 x + width <= tile.get(0) + Game.TILE_SIZE))){
            y = tile.get(1) + Game.TILE_SIZE;
            velocity = 0;
        }

        // if there is no side collision, check for bottom collision
        if (!sideCollision) {
            if ((y / Game.TILE_SIZE + 1 == tile.get(1) / Game.TILE_SIZE) &&
                    (y + height > tile.get(1)) &&
                   ((x >= tile.get(0) && x <= tile.get(0) + Game.TILE_SIZE) ||
                    (x + width >= tile.get(0) &&
                     x + width <= tile.get(0) + Game.TILE_SIZE))) {
                y = tile.get(1) - height;
                if (jumping) {
                    jumping = false;
                    Game.spacePressed = false;
                    dustAfterShowed = false;
                    xAfterJump = x;
                    yAfterJump = y;
                }
                if (falling) {
                    falling = false;
                }
            }
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM