Libgdx有两个使用自己的坐标系绘制的不同视图吗? [英] Libgdx have two different views drawn with own coordinate systems?

查看:41
本文介绍了Libgdx有两个使用自己的坐标系绘制的不同视图吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

看一下这个屏幕截图:

我想将UI分为控件和游戏绘制区域两部分,但是我不希望控件与绘制区域重叠,我希望游戏绘制的 0,0 区域,从控件区域上方开始.

I want to split my UI to two parts, controls and game draw area, but I don't want the controls to overlap the draw area, I want the 0,0 of the game draw area, start above the controls area.

是否可能与 Libgdx 有关?

推荐答案

正如您所说,您希望每个视图都有自己的坐标系,因此分割屏幕技术正如Julian所回答的那样可以解决问题,但正确使用它并不是全部.

As you said you want each view to have its own coordinate system thus splitting the screen technique as answered by Julian will do the trick, but it's not all to properly use it.

要使其完全发挥作用,您应该有2个单独的 OrthographicCamera ,一个用于游戏抽奖视图,另一个用于控制视图.我还建议也为每个摄像机创建2个 Viewport 映射.以我的经验,在使用多个摄像机的情况下,请始终为其创建关联的 Viewport .更适合将来可能发生的更改(即适应任何屏幕分辨率),调试目的(例如检查触摸,位置等).

To make it fully works, you should have 2 separate OrthographicCamera one for game draw view, and another for control view. I suggest also to create 2 Viewport mapping to each camera as well. In my experience, when working in multiple camera situation, always create associate Viewport for it. Better for changes that could introduce in the future (i.e. adapt to any screen resolution), debugging purpose like checking touching, position etc.

因此,将分割技术与摄像头/视口管理相结合,您将拥有强大的系统,可以针对每个区域独立工作.

So combine splitting technique with camera/viewport management, you will have robust system to work for each area independently.

代码

我提供了以下代码,这些代码已在游戏中使用并正常工作,但为了满足您的需要而更改了变量名.它在Kotlin中,但是将其看成Java应该相对容易一些.首先初始化游戏区内容.

I provided the following code as it's used and working in my game, but changed variable names to fit your need. It's in Kotlin, but should be relatively easy to see it as Java. You initialize things first for game area stuff.

// create a camera
gameAreaCamera = OrthographicCamera()
gameAreaCamera.setToOrtho(false, GAME_WIDTH, GAMEVIEW_HEIGHT)
gameAreaCamera.update()

// create a viewport associated with camera
gameAreaViewport = ExtendViewport(GAME_WIDTH, GAMEVIEW_HEIGHT, gameAreaCamera)

下一步,用于控制区域的东西.

Next, for control area stuff.

// create a camera
controlAreaCamera = OrthographicCamera()
controlAreaCamera.setToOrtho(false, GAME_WIDTH, CONTROLVIEW_HEIGHT)
controlAreaCamera.update()

// create a viewport associated with camera
controlAreaViewport = ExtendViewport(GAME_WIDTH, CONTROLVIEW_HEIGHT, controlAreaCamera)

PS :注意每个视图的宽度和高度.它可以根据您的意图占用空间.

PS: Notice width and height of each view. It's set to occupy area as per your intention.

现在,您应该在 render()方法中拥有类似的内容.

Now you should have something like this in render() method.

override fun render() {
    // clear screen
    Gdx.gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f)
    Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT)

    // draw game area
    drawGameArea()
    // draw control area
    drawControlArea()
}

对于您的 drawGameArea(),假定 sb 是您的 SpriteBatch ,并且您将其保留在当前类中,

For your drawGameArea() assume that sb is your SpriteBatch that you maintain it in the current class,

private fun drawGameArea() {
    // the following twos to let system know we will operate against game area's camera
    // set the projection matrix
    sb.projectionMatrix = gameAreaCamera.combined
    // set gl viewport
    Gdx.gl.glViewport(0,0,GAME_WIDTH, GAMEVIEW_HEIGHT)

    // draw your stuff here...
    sb.begin()
    ...
    sb.end()
}

对于 drawControlArea()

private fun drawControlArea() {
    // the following twos to let system know we will operate against control area's camera
    // set the projection matrix
    sb.projectionMatrix = controlAreaCamera.combined
    // set gl viewport
    Gdx.gl.glViewport(0,GAMEVIEW_HEIGHT,GAME_WIDTH, CONTROLVIEW_HEIGHT)

    // draw your stuff here...
    sb.begin()
    ...
    sb.end()
}

请注意 Gdx.gl.glViewport()我们为其提供了目标矩形区域以进行绘制. viewport 并没有直接使用,而是告诉系统哪种屏幕调整大小策略可以将游戏的图形显示在屏幕上,并达到更好的调试目的.您可以在此处了解更多信息.

Note Gdx.gl.glViewport() we supply it with target rectangle area to draw things on. Viewports are not directly used, but it's more to tell the system which kind of screen resizing strategy to fit your game's graphic into screen, and for better debugging purpose. You can read more here.

您将最常使用的两个选项是 ExtendViewport FitViewport .如果您希望游戏出现并覆盖屏幕的整个区域而又不影响纵横比且没有黑条(左侧或右侧为黑色),则 ExtendViewport 可能是您想要的,或者如果您想要类似的效果但带有黑条,因此每个玩家的游戏画面都是相同的(因此,与宽屏玩家相比,它没有任何优势),那么 FitViewport 是您的选择.

Two frequently used options you will use most is ExtendViewport and FitViewport. If you want the game to be appeared and cover entire area of the screen without affect aspect-ratio with no black-bars (black on left-side or right-side), ExtendViewport is likely to be what you want, or if you want the similar effect but with black-bars thus game screen will be the same for every player (thus provide no advantage over player with wide-screen) then FitViewport is your choice.

检查用户界面点击

我想您会需要这个,所以我也应该包括它.每当您需要检查用户是否单击(或点击)了此类UI元素时,都可以在其相应的 update()方法中进行以下检查,以检查触摸位置是否在此类对象的边界范围内区域.

I guess you will need this, so I should include it too. Whenever you need to check whether such UI element is clicked (or tapped) by user, then you can have the following in its corresponding update() method to check whether touching position is within bound of such object's bounding area or not.

以下代码安全且与 ExtendViewport 一起工作得很好,但它也应该与其他 Viewport 一起工作,因为代码不需要来自 ExtendViewport 的任何特定信息code> ExtendViewport .所以是通用的.

The following code safely and work very well with ExtendViewport, but it also should work the same with other Viewport as the code doesn't require any specific information from ExtendViewport. So it's generic.

fun update(dt: Float, cam: Camera: viewport: Viewport) {
    // convert screen coordinate to world coordinate
    val location = Vector3(Gdx.input.getX(), Gdx.input.getY(), 0f)
    cam.unproject(location, viewport.screenX.toFloat(), viewport.screenY.toFloat(), viewport.screenWidth.toFloat(), viewport.screenHeight.toFloat())

    if ((Gdx.input.isTouched() && 
    boundingRect.contains(location.x, location.y)) {
        // do something here...
    }
}

这篇关于Libgdx有两个使用自己的坐标系绘制的不同视图吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆