libgdx 中的多个摄像头(在其他框架中可能类似)
我已经尝试解决这个问题两天了,我已经放弃尝试找到现有的解决方案.
I have been trying to solve this problem for two days and I have given up trying to find an existing solution.
我已经开始学习 libgdx 并完成了一些教程.现在我已经尝试使用我所学到的一切,创建一个简单的横向滚动游戏.现在,我知道有这方面的 libgdx 示例,但我还没有找到将 Box2d 与 scene2d 和演员以及平铺地图相结合的示例.
I have started learning libgdx and finished a couple of tutorials. And now I have tried to use all that I have learned and create a simple side scrolling game. Now, I know that there are libgdx examples of this, but I haven't found a one that incorporates Box2d with scene2d and actors as well as tiled maps.
我的主要问题是相机.
您需要一个用于舞台的相机(据我所知,它用于 SpriteBatch 的投影矩阵传递给演员的 draw() 方法,如果这是错误的,请纠正我)并且您需要一个相机用于调用 render() 方法的 TileMapRender.此外,在某些教程中,GameScreen 中有一个 OrthographicCamera,可在需要时使用.
You need a camera for the Stage (which as far as I know is used for the projection matrix of the SpriteBatch passed to the method draw() at actors, if this is wrong please correct me) and you need a camera for the TileMapRender for calling the render() method. Also, in some of the tutorials there is a OrthographicCamera in the GameScreen, which is used where needed.
我尝试将 OrthographicCamera 对象传递给方法,我尝试在任何地方使用舞台中的相机和 TileMapRenderer 中的相机.前任.
I have tried to pass a OrthographicCamera object to methods, I have tried to use the camera from the Stage and the camera from the TileMapRenderer everywhere. Ex.
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
我也尝试过在各处使用不同的相机.
I have also tried to use different cameras everywhere.
在尝试了所有这些之后,我没有注意到确切的时间发生了什么,但我会列出发生了什么:
After trying all of this I haven't noted what happens exactly when but I will list what happens :
- 屏幕上什么都没有(可能相机远离绘制的东西)
- 我可以从 debugRenderer 中看到平铺地图和轮廓(我也使用 debugRender,但我不认为它会干扰相机),但演员的精灵不可见(可能在屏幕外)李>
- 我可以看到我应该看到的所有内容,但是当我尝试移动应该跟随他的 Actor 和相机时,精灵的移动速度比身体快(绿色调试方块).
所以我的主要问题是:
- 我不明白当您拥有多个摄像头时会发生什么.通过"您在屏幕上实际看到的是哪一个?
- 我应该使用多台相机吗?如何使用?
另外,我认为我应该提到我正在使用 OpenGL ES 2.0.
Also, I thought that I should mention that I am using OpenGL ES 2.0.
很抱歉这个问题太长了,但我想我应该详细描述一下,因为这对我来说有点复杂.
I am sorry for the long question, but I thought that I should describe in detail, since it's a bit complicated for me.
推荐答案
你实际上同时看透了所有这些.虽然他们可能会看到一个完全不同的世界,但他们都将他们的观点呈现在屏幕上.您可以使用多台相机,也可以只使用一台.如果您只使用一个,则需要确保在绘制 TiledMap、使用 Actors 的舞台以及可能用于可选的 Box2DDebugRenderer 之间正确更新投影矩阵.
You actually see through all of them at the same time. They might look at a completely different world though, but all of them render their point of view to the screen. You can use several cameras, or just one. If you use only one you need to make sure that you update the projection matrix correctly, between drawing the TiledMap, your Stage with Actors and maybe for the optional Box2DDebugRenderer.
我会为 Box2DDebugRenderer 使用额外的摄像头,因为您以后可以轻松地将其丢弃.我假设您使用转换因子将米转换为像素,反之亦然.1:1的比例不会很好.我总是使用介于 1m=16px 和 1m=128px 之间的东西.
I'd use an extra Camera for the Box2DDebugRenderer, because you can easily throw it away later. I assume you use a conversion factor to convert meters to pixels and the other way around. Having a 1:1 ratio wouldnt be very good. I always used something between 1m=16px and 1m=128px.
所以你以这种方式初始化它,并将它用于调试渲染器:
So you initialize it this way, and use that one for your debugging renderer:
OrthographicCamera physicsDebugCam = new OrthographicCamera(Gdx.graphics.getWidth() / Constants.PIXEL_PER_METER, Gdx.graphics.getHeight() / Constants.PIXEL_PER_METER);
对于您的 TiledMapRenderer,您也可以使用额外的摄像头,但该摄像头仅适用于屏幕坐标,因此无需转换:
For your TiledMapRenderer you may use an extra camera as well, but that one will work in screen-coordinates only, so no conversion:
OrthographicCamera tiledMapCam = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
TiledMap 将始终在 (0, 0) 处呈现.所以你需要使用相机在地图上四处走动.它可能会跟随一个主体,因此您可以通过以下方式对其进行更新:
The TiledMap will always be rendered at (0, 0). So you need to use the camera to move around on the map. It will probably follow a body, so you can update it via:
tiledMapCam.position.set(body.getPosition().x * Constants.PIXELS_PER_METER, body.getPosition().y * Constants.PIXELS_PER_METER)
或者如果它跟随一个演员:
Or in case it follows an Actor:
tiledMapCam.position.set(actor.getX(), actor.getY())
我实际上还没有将scene2d 与Box2D 一起使用,因为我不需要与我的游戏对象进行太多交互.您需要在这里实现一个自定义的 PhysicsActor,它扩展了 Actor 并通过将 body 作为属性来构建从 scene2d 到 Box2D 的桥梁.它必须在每个更新步骤中基于 Body 设置 Actor 的位置、旋转等.但在这里你有几个选择.您可以重复使用 tiledMapCam 并在屏幕坐标中工作.在这种情况下,您需要始终记住在更新 actor 时与 Constants.PIXELS_PER_METER 相乘.或者您将使用具有相同视口的另一个摄像头,例如physicsDebugCam.在这种情况下,不需要转换,但我不确定这是否会干扰某些特定于场景的东西.
I actually haven't used scene2d together with Box2D yet, because I didn't need to interact very much with my game objects. You need to implement a custom PhysicsActor here, which extends Actor and builds the bridge from scene2d to Box2D by having a body as a property. It will have to set the Actors position, rotation etc based on the Body at every update-step. But here you have several options. You may re-use the tiledMapCam and work in screen-coordinates. In this case you need to always remember to multiply with Constants.PIXELS_PER_METER when you update your actor. Or you will use another cam with the same viewport like the physicsDebugCam. In this case no conversion is needed, but I'm not sure if this might interfere with some scene2d-specific things.
对于 ParallaxBackground,您也可以使用另一个摄像头,对于 UI,您可以再次使用另一个舞台和另一个摄像头...或者通过正确重置它们来重复使用其他摄像头.这是您的选择,但我认为几个相机不会对性能产生太大影响.更少的重置和转换甚至可能会改善它.
For a ParallaxBackground you may use another camera as well, for UI you can use another stage and another camera again... or reuse others by resetting them correctly. It's your choice but I think several cameras do not influence performance much. Less resetting and conversions might even improve it.
设置完所有内容后,您只需渲染所有内容,使用正确的相机并将每个层"/视图"渲染在彼此之上.首先是 ParallaxBackground,然后是 Tiledmap,然后是 Entity-Stage,然后是 Box2DDebugging 视图,然后是 UI-stage.
After everything is setup, you just need to render everything, using the correct cameras and render every "layer"/"view" on top of each other. First a ParallaxBackground, then your Tiledmap, then your Entity-Stage, then your Box2DDebugging view, then your UI-stage.
一般记得在更改相机的任何内容后调用 spriteBatch.setProjectionMatrix(cam.combined);
并使用 cam.update()
.
In general remember to call spriteBatch.setProjectionMatrix(cam.combined);
and using cam.update()
after you changed anything of your camera.
相关文章