Android libgdx游戏中的平铺碰撞检测

时间:2013-09-17 02:20:33

标签: java android libgdx collision-detection

在这个游戏中,我正在写我到目前为止只是用瓦片来处理碰撞检测:

我将地图向左滚动8个单位。然后我检查我的角色右侧是否有一个具有“碰撞”属性的瓷砖发生碰撞。如果发生碰撞,那么我将我的角色定位,使其右边缘像素值等于图块的左边缘。

现在检查垂直碰撞检测,我检查角色的右下角和左下角。如果任一角落在“碰撞”区块中,那么我将角色的y值设置为等于区块的顶部(即,如果它与实体区块碰撞,则它将始终显示在该区块的顶部)。

这种垂直碰撞检测工作直到我碰壁。由于垂直碰撞检查总是将角色推到瓷砖的顶部,如果我的角色跳跃并落在墙的中心,那么他将被卡在墙上的一块瓷砖的顶部,直到你按下跳转,然后他立即向上移动到下一个瓷砖的顶部。

解决这种垂直碰撞检测的更好方法是什么?我在考虑永远不要让角色完全拥抱“墙”瓦片,这样他的右边缘始终是1像素从墙砖上,这样我仍然可以对角色的右角进行检查,它永远不会真正击中那堵墙(因此,如果在墙旁边,角色仍然会掉落)。这看起来很草率。有没有更好的办法?我整天都在研究这个问题,似乎无法找到一个好的解决方案。

代码如下所示:

public void render() 
{       

    Gdx.gl.glClearColor(0, 0, 0, 1);
    Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

    gameTime += Gdx.graphics.getDeltaTime();

    characterDisplay = characterAnimation.getKeyFrame(gameTime, true);




    TiledMapTileLayer layer = (TiledMapTileLayer)tiledMap1.tiledMap.getLayers().get(0);

    float x;
    float x1; 
    float x2;
    x1 = ((characterPosition.x + characterWidth)/tileWidth);
    x2 = (-tileRenderer.tiledMap.x); 
    x = x1 + x2;


    if (isFalling)
        characterPosition.y -= FALLING_SPEED;

    float yBottom;
    float y1 = (int)((characterPosition.y)/tileWidth) + 1; 
    yBottom = y1;



    tileRenderer.tiledMap.x -= .2;


    if (layer.getCell((int)x, (int)yBottom).getTile().getProperties().containsKey("collision"))
    {
        characterPosition.x = ((x + tileRenderer.tiledMap.x )* tileWidth) - characterWidth;
    }


    y1 = (int)(characterPosition.y/tileWidth);
    yBottom = y1;

    x1 = ((characterPosition.x + characterWidth)/tileWidth);
    x2 = (-tileRenderer.tiledMap.x); 
    x = x1 + x2;    

    if ((layer.getCell((int)x, (int)yBottom).getTile().getProperties().containsKey("collision") || layer.getCell((int)x - 1, (int)yBottom).getTile().getProperties().containsKey("collision")))
    {

        characterPosition.y = (yBottom * tileHeight) + tileHeight;
        isFalling = false;
    }

    tileRenderer.render();      




    //draw textures
    batch.setProjectionMatrix(camera.combined);
    batch.begin();
    batch.draw(characterDisplay, characterPosition.x, characterPosition.y);
    batch.end();


    //handle user input
    handleUserInput();
}

1 个答案:

答案 0 :(得分:1)

而不是简单地设置角色"在外面"你可能想要考虑"推动"瓦片中的角色。因此,如果你跳到墙上,代码将识别你以前的位置和运动矢量,并意识到你首先在x方向上相撞。然后你的演员会被推回去#34;沿着它的运动矢量,直到它碰到它碰撞的物体。然后再次检查以确保您没有碰到任何东西并重复。这也有助于确保您不会将角色嵌入墙/地板。

有效地,尝试迭代而不是一次完成。

你也可以先发制人 - 也就是说,在你搬家之前检查一下。有关示例,请参阅here

还有box2d,这种复杂程度非常快。它可以比自己动手更干净地进行碰撞检测,并且对于平台游戏来说非常棒。