LibGDX - Tilemap墙碰撞检测问题

时间:2015-06-20 20:56:49

标签: java libgdx collision-detection tiled

我从另一个网络教程(SuperKoalio)中获取了一些关于检测我的播放器与tilemap图层中称为“墙”的图块之间的碰撞的代码。该游戏是RPG(Gauntlet)风格的游戏。碰撞检测通常有效,但偶尔玩家将穿过墙壁并在地图上显得更远,或突然超出地图范围。它几乎就像有差距。

我使用的代码似乎会立即检查播放器左侧和右侧的磁贴,然后对播放器上方和下方的磁贴执行另一次检查。我认为这个想法基本上没问题,但是这并没有考虑到对角线的移动,我认为这可能会导致玩家穿过墙壁。

我的检测程序中的代码如下:

public void checkCollisions(float delta) {
    ////////////////////////////////////////////////////////////////
    //collision detection - X
    int startX, startY, endX, endY;
    startX  = (int) (position.x);
    endX    = (int) (position.x + 1);
    startY  = (int) (position.y);
    endY    = (int) (position.y);

    playerRect = rectPool.obtain();
    playerRect.set(position.x, position.y, 1.0f, 1.0f);

    getWalls(startX, startY, endX, endY, walls);

    for (Rectangle wall : walls)
    {
        //Rectangle rectangle = rectangleObject.getRectangle();
        if (playerRect.overlaps(wall) && velocity.x != 0) {
            velocity.x = 0;
            if(facingDir == 3) {
                position.x = wall.x+1.1f;
            } else if(facingDir == 4) {
                position.x = wall.x-1.1f;
            }

            break;

        }
        // collision happened
        //break;
    }


    playerRect.x = position.x;


    // if the player is moving upwards, check the tiles to the top of it's
    // top bounding box edge, otherwise check the ones to the bottom
    if (velocity.y > 0)
    {
        startY = (int) (position.y);
        endY = (int) (position.y + 1.1f);
    }
    else
    {
        startY = endY = (int) (position.y);
    }

    startX = (int) (position.x);
    endX = (int) (position.x + 1);

    getWalls(startX, startY, endX, endY, walls);

    //playerRect.y = velocity.y;

    for (Rectangle wall : walls)
    {
        if (playerRect.overlaps(wall) && velocity.y != 0)
        {
            velocity.y = 0;
            //velocity.x = 0;
            if(facingDir == 1) {
                position.y = wall.y - 1.1f;
            } else if(facingDir == 2) {
                position.y = wall.y + 1.1f;
            }
            break;
        }
        break;
    }

    playerRect.y = position.y;

    rectPool.free(playerRect);

    velocity.x = 0;
    velocity.y = 0;

}

加载墙层的“getWalls()”方法如下:

/**
 * Get the walls of the map for collision detection between the player and the walls, so that
 * the player cannot pass through.
 * @param startX
 * @param startY
 * @param endX
 * @param endY
 * @param walls
 */
private void getWalls(int startX, int startY, int endX, int endY, Array<Rectangle> walls)
{
    TiledMapTileLayer layer = (TiledMapTileLayer) MapRenderer.map.getLayers().get("walls");
    layer.setVisible(false);
    rectPool.freeAll(walls);
    walls.clear();

    for (int y = startY; y <= endY; y++)
    {
        for (int x = startX; x <= endX; x++)
        {
            TiledMapTileLayer.Cell cell = layer.getCell(x, y);
            if (cell != null)
            {
                Rectangle rect = rectPool.obtain();
                rect.set(x, y, 1, 1);
                walls.add(rect);
            }
        }
    }
}

有没有人知道为什么这个例程不是很强大?

我真的希望能够尽可能简单有效地实现这一目标。同样的技术也需要应用于敌人,以阻止他们穿过墙壁。

当然必须有一种更好,更可靠的方法,或者只是我的代码中存在缺陷/缺口 - 例如,如果我是对角线方向的墙吗?

0 个答案:

没有答案