【问题标题】:Changing the Coordinate System in LibGDX (Java)在 LibGDX (Java) 中更改坐标系
【发布时间】:2011-10-10 03:53:23
【问题描述】:

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

这让我头疼不已,主要是因为我正在移植一个我已经用通常的坐标系(其中 0,0 位于左上角)制作的游戏。

我的问题:有什么简单的方法可以改变这个坐标系吗?

【问题讨论】:

  • 当然,这就是我现在正在做的事情。但是有什么办法可以翻转坐标系。就像用我想要的坐标系创建一个投影矩阵一样。或者告诉 Spritebatch 根据某个坐标系进行绘制......我一直看起来很疯狂,但我似乎找不到任何特别的东西......(如果有,实际代码是什么)
  • 这确实是一场噩梦。 SpriteBatch 和 sprites 之类的东西从左下角开始。输入和纹理区域之类的东西从左上角开始。导致超级尴尬的编码和在你脑海中转来转去的事情,所以你的眼睛经常开始跳出来。无论如何,我建议习惯它,转动相机会导致图像翻转,然后你需要将所有东西都翻转回来,但不是所有东西都只是大多数东西,并且让它们出乎意料地绘制。 LibGDX 很棒,但是坐标系统有严重的问题。习惯就好了。

标签: java 2d sprite coordinate-systems libgdx


【解决方案1】:

如果你使用相机(你应该这样做),改变坐标系非常简单:

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

如果您使用 TextureRegions 和/或 TextureAtlas,除此之外您需要做的就是调用 region.flip(false, true)。

我们默认使用 y-up 的原因(您可以如上图所示轻松更改)如下:

  • 您的模拟代码很可能会使用带 y-up 的标准欧几里得坐标系
  • 如果你去 3D,你有 y-up
  • 默认坐标系是 OpenGL 中的右手坐标系,y 向上。当然,您可以通过一些矩阵魔法轻松改变这一点。

libgdx 中我们使用 y-down 的唯一两个地方是:

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

同样,您可以使用相机或少量矩阵数学轻松地将使用的坐标系更改为您想要的任何坐标系。

【讨论】:

  • 创作者自己的回答。谢谢,很有用!
  • @badlogic 您指定他应该使用相机,但仅使用 SpriteBatch.draw 方法并自己处理世界滚动和截锥体剔除会导致什么问题?我正在开发一款自上而下的策略游戏。
  • 我认为它的开发方式是有原因的,但是如果您根本不使用任何相机,而只是使用 SpriteBatch.draw( )?我有 Pasman 的确切问题。
  • @Pasman,你可以使用 batch.getProjectionMatrix().setToOrtho2D()。
  • 一切都颠倒了!我可以翻转区域但不能翻转纹理。
【解决方案2】:

只是稍微扩展一下上面 badlogic 所说的内容,如果您使用的是 TextureAtlas(带有 TextureRegions),您需要翻转它们,正如 badlogic 所说,除了相机工作。如果您使用的是 TextureAtlas,则可以在加载图集后立即使用此代码:

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);
}

【讨论】:

  • 我怎样才能翻转一个普通的Texture?这些现在在我的游戏中被颠倒了。
【解决方案3】:

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

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

【讨论】:

  • 嗯,这不是我想要的。但是我这样做了,效果很好,而且也没有太多编码。(此外,我一直在寻找,我认为没有其他办法)谢谢!
  • 不确定你是不是这个意思,但我不认为一个“神”类能做到这一切是个好主意,所以我试图扩展我需要的所有类并覆盖根据需要的方法。也不是一个很好的解决方案。
  • 嗯,实际上我想我会尝试使用 OrthographicCamera 类的解决方法,看看效果如何。
【解决方案4】:

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

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

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

【讨论】:

  • 它实际上是一个非常强大的Android游戏开发库。正如评估所指出的,唯一奇怪的是坐标处理。
  • 因此,如果您了解相机或矩阵的使用方法,您就可以拥有您真正想要的任何坐标系。 :)
  • 但是如果你没有使用相机,你似乎不走运,需要将 API 包装在外观中来改变这一点。 Arrrgh ..为什么要使用荒谬的标准左上角坐标系以外的任何东西?为什么YYYYYYYYYYYYYY? :(
  • @Perce,因为数学。
  • 嘿。因此,其他 9,999 个使用左上角坐标系的库没有使用数学。有趣的。 :p
【解决方案5】:

我刚刚创建了一个扩展SpriteBatch 的类,它覆盖了添加y = Gdx.graphics.getHeight() - y - height 的某些方法。简单但有效。

【讨论】:

    【解决方案6】:

    我能够通过 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(),您需要使用所有这些参数,因为您需要在末尾使用布尔值flipY 来翻转纹理(我可能会扩展SpriteBatch 或创建一个实用方法来避免一直传递这么多参数。)
    • 注意batch.setProjectionMatrix(cam.combined);在渲染()中

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多