Libgdx有两个不同的视图用自己的坐标系绘制?

时间:2017-08-23 06:39:10

标签: java libgdx

看一下这个截图:

enter image description here

我想将我的UI拆分为两个部分,控件和游戏绘图区域,但我不希望控件与绘图区域重叠,我想要游戏绘制区域的0,0,开始在控制区域之上。

这可能与Libgdx有关吗?​​

2 个答案:

答案 0 :(得分:2)

正如你所说的,你希望每个视图都有自己的坐标系,因此splitting the screen technique如朱利安所回答的那样可以解决这个问题,但并不是所有都能正确使用它。

为了使其完全有效,你应该有两个单独的OrthographicCamera一个用于游戏绘制视图,另一个用于控制视图。我还建议为每个摄像头创建2 Viewport映射。根据我的经验,在多个摄像机情况下工作时,请始终为其创建关联Viewport。更好地适应未来可能引入的变化(即适应任何屏幕分辨率),调试目的,如检查触摸,位置等。

因此,将分割技术与摄像机/视口管理相结合,您将拥有可靠的系统,可以独立地为每个区域工作。

<强>代码

我提供了以下代码,因为它在我的游戏中使用和工作,但更改了变量名称以满足您的需要。它在Kotlin中,但应该相对容易将其视为Java。 你首先为游戏领域的东西初始化。

// 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)

接下来,对于控制区域的东西。

// 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 :注意每个视图的宽度和高度。根据你的意图设置占据区域。

现在你应该在render()方法中使用这样的东西。

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

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不是直接使用的,但更多的是告诉系统哪种屏幕大小调整策略使游戏的图形适合屏幕,以及更好的调试目的。您可以阅读更多here

您最常用的两个常用选项是ExtendViewportFitViewport。如果您希望游戏出现并覆盖屏幕的整个区域而不影响宽高比而没有黑条(左侧或右侧黑色),ExtendViewport很可能是您想要的,或者如果你想要类似的效果,但是使用黑条,那么每个玩家的游戏画面都是相同的(因此没有优于宽屏幕的玩家),那么FitViewport是你的选择。

检查点按用户界面

我猜你会需要这个,所以我也应该把它包括在内。 每当您需要检查用户是否单击(或点击)此类UI元素时,您可以在其对应的update()方法中使用以下内容来检查触摸位置是否在此对象的边界区域的范围内。 / p>

以下代码安全地与ExtendViewport一起使用,但它也应该与其他Viewport一样,因为代码不需要ExtendViewport中的任何特定信息。所以它是通用的。

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...
    }
}

答案 1 :(得分:1)

您可以使用两个相机并按照图像中所示放置它们。我认为这篇文章可以给你一个提示:Split-Screen in LibGDX