libgdx中有多个摄像头(在其他框架中可能类似)


问题内容

我已经尝试解决此问题两天了,我已经放弃了寻找现有解决方案的尝试。

我已经开始学习libgdx,并完成了一些教程。现在,我尝试使用所学的知识,并创建一个简单的侧滚动游戏。现在,我知道有libgdx的例子,但是我还没有找到一个将Box2d与scene2d和actor以及平铺的地图结合在一起的例子。

我的主要问题是相机。

您需要一个用于舞台的摄像机(据我所知,它用于将SpriteBatch的投影矩阵传递给actor的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,但我不认为它会干扰相机),但是actor的精灵是不可见的(可能不在屏幕上)
  • 我可以看到所有我应该看到的东西,但是当我尝试移动应该跟随他的Actor和Camera时,子画面的速度比主体快(绿色的调试方块)。

所以我的主要问题是:

  • 我不明白当您有多台摄像机时会发生什么。“通过”您实际上在蒙太奇上看到哪一个?
  • 我应该使用多台相机吗?

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

很长的问题我很抱歉,但是我认为我应该详细描述,因为这对我来说有点复杂。


问题答案:

您实际上可以同时查看所有这些内容。他们可能会看到一个完全不同的世界,但是所有人都将自己的观点呈现在屏幕上。您可以使用多个摄像机,也可以仅使用一个。如果只使用一个,则需要确保正确地更新投影矩阵,介于绘制TiledMap,带有Actors的舞台以及可能的可选Box2DDebugRenderer之间。

我将为Box2DDebugRenderer使用一个额外的Camera,因为稍后可以轻松将其丢弃。我假设您使用转换因子将米转换为像素,反之亦然。拥有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)

或者,如果跟随演员:

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

实际上,我还没有将Scene2d和Box2D一起使用,因为我不需要与游戏对象进行太多交互。您需要在此处实现自定义PhysicsActor,该扩展自Actor并通过将主体作为属性来构建从scene2d到Box2D的桥梁。在每个更新步骤中,都必须根据主体设置Actor的位置,旋转等。但是在这里您有几种选择。您可以重新使用tiledMapCam并在屏幕坐标中进行操作。在这种情况下,您始终需要记住在更新actor时要与Constants.PIXELS_PER_METER相乘。否则,您将使用与PhysicalDebugCam相同视口的另一个凸轮。在这种情况下,不需要转换,但是我不确定这是否会干扰某些特定于Scene2d的事物。

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

设置完所有内容后,您只需要使用正确的相机来渲染所有内容,并将每个“层”
/“视图”彼此叠加即可。首先是ParallaxBackground,然后是Tiledmap,然后是Entity-
Stage,然后是Box2DDebugging视图,然后是UI阶段。

通常,记住在更换任何相机后都要打电话spriteBatch.setProjectionMatrix(cam.combined);和使用cam.update()