在LibGDX (Java)中改变坐标系统



LibGDX有一个坐标系统,(0,0)位于左下角。(如图片:https://i.stack.imgur.com/jVrJ0.png)

这让我很头疼,主要是因为我要移植一款我已经用常规坐标系统制作的游戏(0,0位于左上角)。

我的问题:是否有任何简单的方法来改变这个坐标系?

如果你使用相机(你应该)改变坐标系统是非常简单的:

camera= new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
camera.setToOrtho(true, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());

如果你使用TextureRegions和/或TextureAtlas,你所需要做的就是调用region。翻转(假,真)。

我们默认使用y-up的原因如下(你可以很容易地改变,如上所示):

  • 你的模拟代码很可能会使用一个标准的欧几里德坐标系统与y-up
  • 如果是3D模式,则是y-up
  • 默认坐标系是OpenGL中的右手坐标系,y向上。当然,你可以很容易地用一些矩阵魔法来改变这一点。

在libgdx中只有两个地方使用了y-down:

  • 像素图坐标(左上角原点,y轴向下)
  • 在窗口坐标中给出的触摸事件坐标(左上角原点,y轴向下)

同样,你可以很容易地改变使用的坐标系统,无论你想使用相机或一点点矩阵数学。

只是稍微扩展一下badlogic上面所说的,如果你正在使用TextureAtlas(带有TextureRegions),你需要翻转它们,正如badlogic所说,除了相机工作。如果你正在使用TextureAtlas,你可以在加载你的atlas之后使用这段代码:

String textureFile = "data/textures.txt";  
atlas = new TextureAtlas(Gdx.files.internal(textureFile), Gdx.files.internal("data"));  
// Let's flip all the regions.  Required for y=0 is TOP
Array<AtlasRegion> tr = atlas.getRegions();      
for (int i = 0; i < tr.size; i++) {
  TextureRegion t = tr.get(i);
  t.flip(false, true);
}

如果您想隐藏转换,并且在设置一次之后不考虑它,您可以创建一个继承您需要的所有功能的类,但在将其传递给其父类的函数之前首先转换坐标。不幸的是,这将花费很多时间。

您也可以创建一个方法,对整个Coordinate对象(或您正在使用的任何对象)进行简单的y' = height - y转换,并在每次操作之前调用它一次。

有趣的图形库,我会说。我从下面的链接中找到了这个评估:

另一个问题是在Libgdx的不同部分使用了不同的坐标系。有时坐标轴的原点在左下角,y轴向上,有时在雪碧的左上角向下指向。当画网格原点甚至在屏幕的中心。这导致相当多的混乱和额外的工作,把所有的东西在屏幕上的正确位置

http://www.csc.kth.se/utbildning/kandidatexjobb/datateknik/2011/rapport/ahmed_rakiv_OCH_aule_jonas_K11072.pdf

我刚刚做了一个扩展SpriteBatch的类,它覆盖了添加y = Gdx.graphics.getHeight() - y - height的某些方法。

我能够得到纹理字体正确渲染使用建议的翻转坐标系统通过OrthographicCamera。我是这样做的:

private SpriteBatch batch;
private BitmapFont font;
private OrthographicCamera cam;
private Texture tex;
@Override
public void create () {
    batch = new SpriteBatch();
    
    font = new BitmapFont(true);
    font.setColor(Color.WHITE);
    
    cam = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
    cam.setToOrtho(true, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
    tex = new Texture("badlogic.jpg");
}
@Override
public void dispose() {
    batch.dispose();
    font.dispose();
    tex.dispose();
}
@Override
public void render () {
    cam.update();
    batch.setProjectionMatrix(cam.combined);
    
    Gdx.gl.glClearColor(0, 0, 0, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    batch.begin();
    
    font.draw(batch, "Test", 50, 50);
    batch.draw(tex, 100, 100, tex.getWidth(), tex.getHeight(), 0, 0, tex.getWidth(), tex.getHeight(), false, true);
    
    batch.end();
}

需要注意的重要事项是:

  • BitmapFont构造函数,布尔值翻转字体
  • 对于batch.draw(),你需要使用所有这些参数,因为你需要在最后使用布尔翻转来翻转纹理(我可能会扩展SpriteBatch或创建一个实用程序方法来避免一直传递这么多参数)。
  • 注意batch.setProjectionMatrix (cam.combined);在渲染()

现在我们将看看我今晚晚些时候是否会回到这里进行编辑,以解决所有这些问题或发现。

最新更新