LibGDX如何使用多个视口/相机?

6
在我目前正在开发的LibGDX游戏中,我遇到了与Viewports相关的问题。 我试图创建两个视口-一个包含整个屏幕,包括控件,另一个在第一个视口中央包含游戏的可视化内容。这就是我的意思。 然而,使用这些视口时我遇到了一些问题。 首先,放置在FitViewportapply中的平铺地图和玩家没有被看到(要么没有被渲染,要么超出了可见屏幕空间),但我的Rayhandler的光线被看到了(并且比分配的1:1比率更扩散)。证明
private OrthographicCamera camera;    
Viewport v1;
Viewport v2;
//...
RayHandler devRay;
//...
TiledMap map;
OrthogonalTiledMapRenderer tmr;
Player player;

@Override
public void show() {    
    camera = new OrthographicCamera(VIRTUAL_WIDTH, VIRTUAL_HEIGHT);
    camera.setToOrtho(false,Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
    //...
    v1 = new ScreenViewport();
    v2 = new FitViewport(160, 160, camera);
    //...
    tmr = new OrthogonalTiledMapRenderer(map);
    tmr.setView(camera);
    RayHandler.useDiffuseLight(true);
    devRay = new RayHandler(world);
}
public void render(float delta) {

    Gdx.gl.glClearColor(1,1,1,1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    v1.apply();
    //Draw Controls

    v2.apply();
    //Draw Visuals  
    tmr.render(); //Tiled Map Renderer
    player.render();
    devRay.updateAndRender();
    //...
}   

我猜我完全错过了Viewport的重点。我想知道是否有任何方法可以在我的项目中分离可播放区域和控制区域,以便例如,我可以移动FitViewport的相机而不会使游戏视图占用超过1:1的比例。谢谢你的帮助!

2个回答

4
我通常做的是使用单个相机来渲染世界,然后通过在最后绘制舞台stage.draw() 来覆盖hud。对于此,舞台非常出色。显然,这会遮挡一些本应该在没有hud时可见的游戏世界,因此如果您真的想要多个“视口”,那么您必须使用Viewports进行处理。
如果选择正确的Viewport,则可以轻松实现并处理所有内容。设置相机后,可以像这样创建视图口: if you pick the correct one
    camera = new OrthographicCamera(1920 / 2, 1080);
    //1920, 1080 for sake of example. This could be anything and it is often
    // better to not think in pixels but in world units.

    viewport = new FitViewport(camera.viewportWidth, camera.viewportHeight, camera);
    viewport.setScreenBounds(0, 0, Gdx.graphics.getWidth() / 2, Gdx.graphics.getHeight());

这将通过使用setScreenBounds(...)在屏幕左侧创建一个视口。由于我们只在相机的一半屏幕上绘制东西,因此必须匹配宽高比,否则会出现拉伸的情况。
为了澄清,有时这可能有点令人困惑:
float worldWidth, worldHeight; // How much of the world to display
viewport = new FitViewport(worldWidth, worldHeight, camera);

int screenPosX, screenPosY, screenWidth, screenHeight; 
// The position of the viewport where 0, 0 is bottom left and 
// Gdx.graphcis.getWidth, Gdx.graphics.getHeight is top right
viewport.setScreenBounds(screenPosX, screenPosY, screenWidth, screenHeight);

实际上,你不需要指定相机的宽度和高度,因为一旦将该相机连接到vp并使用vp.apply()进行覆盖,它就会被覆盖。

update()方法中,在你绘制特定视口上的任何内容之前,你必须先应用视口viewport.apply()


4
我遭遇了同样的问题。在官方文档中有一个答案。

多个视口 当使用具有不同屏幕大小的多个视口(或者您使用其他设置glViewport的代码)时,需要在绘制之前应用视口,以使glViewport为该视口设置。

viewport1.apply();
// draw
viewport2.apply();
// draw

使用多个阶段时:
stage1.getViewport().apply();
stage1.draw();
stage2.getViewport().apply();
stage2.draw();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接