libgdx中的多个相机(其他框架可能类似)

10

我已经试了两天来解决这个问题,但是现在放弃寻找现有的解决方案。

我开始学习libgdx并完成了一些教程。现在,我试图使用我所学的创建一个简单的侧向滚动游戏。我知道有libgdx的这种示例,但我没有找到一个将Box2d与scene2d和actors以及平铺地图相结合的解决方案。

我的主要问题在于相机。

您需要一个相机来为舞台(据我所知,用于传递给演员的SpriteBatch的投影矩阵的方法draw(),如果有误,请纠正我),并且您需要一个相机来呼叫TileMapRender的render()方法。此外,在某些教程中,GameScreen中有一个OrthographicCamera,可以根据需要使用它。

我尝试将OrthographicCamera对象传递给方法,我尝试在所有地方都使用来自舞台和TileMapRenderer的相机。 例如:

OrthographicCamera ocam  = new OrthographicCamera(FRUSTUM_WIDTH, FRUSTUM_HEIGHT);
stage.setCamera(ocam); // In the other cases i replace ocam with stage.getCamera() or the one i use for the tileMap Render
tileMapRenderer.render(ocam);
stage.getSpriteBatch().setProjectionMatrix(ocam.combined); // I am not sure if this is needed

我也尝试在不同的位置使用不同的相机。

尝试了所有这些后,我没有注意到发生了什么,但我会列出发生了什么:

  • 屏幕上什么也没有(可能是相机离绘制的东西太远)
  • 我可以从debugRenderer中看到平铺地图和轮廓(我也使用debugRender,但我不认为它会干扰相机),但演员的精灵不可见(可能在屏幕外)
  • 我可以看到应该看到的一切,但当我尝试移动演员和相机(应该跟随演员),精灵比身体(绿色调试正方形)移动得更快。

所以我的主要问题是:

  • 我不明白当你有多个相机时会发生什么。你实际上是通过哪一个看到监视器上的画面?
  • 我应该使用多个相机吗?如何使用?

另外,我想提到我正在使用OpenGL ES 2.0。

非常抱歉问题很长,但我觉得我应该详细描述,因为对我来说有点复杂。


你是否调用了 stage.act() 和 stage.draw() 来渲染舞台? - Vikalp Jain
1个回答

18
你实际上同时看到它们所有的内容。虽然它们可能看起来处于完全不同的世界中,但它们都将自己的视角呈现到屏幕上。 你可以使用多个相机,也可以只使用一个。如果只使用一个,则需要确保在绘制TiledMap、有演员的舞台和可选的Box2DDebugRenderer之间正确更新投影矩阵。
我建议为Box2DDebugRenderer使用额外的相机,因为你可以很容易地将其丢弃。我假设你使用转换因子将米转换为像素和反之。具有1:1比例并不是很好。我总是使用1m=16px至1m=128px之间的某些值。
因此,你可以这样初始化它,并在调试渲染器中使用它:
OrthographicCamera physicsDebugCam = new OrthographicCamera(Gdx.graphics.getWidth() / Constants.PIXEL_PER_METER, Gdx.graphics.getHeight() / Constants.PIXEL_PER_METER);

对于您的TiledMapRenderer,您也可以使用额外的相机,但是该相机仅适用于屏幕坐标,因此不需要进行转换:

OrthographicCamera tiledMapCam = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());

TiledMap将始终呈现在(0, 0)位置。因此,您需要使用相机在地图上移动。它可能会跟随一个主体,所以您可以通过以下方式更新它:

tiledMapCam.position.set(body.getPosition().x * Constants.PIXELS_PER_METER, body.getPosition().y * Constants.PIXELS_PER_METER)

或者,如果它跟随在一个 Actor 之后:

tiledMapCam.position.set(actor.getX(), actor.getY())

我实际上还没有将scene2d和Box2D一起使用,因为我不需要与我的游戏对象进行太多交互。在此处,您需要实现一个自定义的PhysicsActor,它扩展了Actor,并通过具有body属性来构建从scene2d到Box2D的桥梁。它必须根据每次更新步骤中的Body设置演员的位置、旋转等。但是在这里您有几个选择。您可以重用tiledMapCam并在屏幕坐标系中工作。在这种情况下,当您更新演员时,您需要始终记住乘以Constants.PIXELS_PER_METER。或者,您将使用具有与物理DebugCam相同视口的另一个摄像机。在这种情况下,无需进行转换,但我不确定这是否会干扰一些特定于场景2d的事情。

对于ParallaxBackground,您也可以使用另一个摄像机,对于UI,您可以再次使用另一个舞台和另一个摄像机...或者通过正确重置它们来重复使用其他内容。这是您的选择,但我认为几个摄像机不会对性能产生太大影响。少量重置和转换甚至可能会改善它。

完成所有设置后,您只需要使用正确的摄像机呈现所有内容,并将每个“层”/“视图”逐一放置在其上。首先是ParallaxBackground,然后是Tiledmap,然后是Entity-Stage,然后是Box2DDebugging视图,最后是UI-stage。

总的来说,请记住在更改相机的任何内容之后调用 spriteBatch.setProjectionMatrix(cam.combined); 并使用 cam.update()


我有一个类似的问题;我正在使用自定义单位和投影(作为舞台的一部分)渲染平铺地图,并且我想在其上方渲染像FPS这样的文本调试UI。然而,即使我为调试UI使用单独的OrthographicCamera并将其拉伸到屏幕w/h,并将其设置在用于呈现文本的精灵批处理上,它仍将根据地图边界而不是我的屏幕边界进行渲染。在调用stage.draw()之后并在debugUi.render()之前,我必须重置某些内容以防止发生这种情况吗?我一定漏掉了什么。 - mxk
@Matthias 请创建一个新的问题,包括相关代码。 - noone
确信:https://dev59.com/BYXca4cB1Zd3GeqPEzJC - mxk

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