libgdx坐标系渲染和触摸输入之间的差异

我有一个呈现PNG图像的屏幕(BaseScreen实现了Screen界面)。 点击屏幕后,它会将角色移动到触摸位置(用于测试目的)。

public class DrawingSpriteScreen extends BaseScreen { private Texture _sourceTexture = null; float x = 0, y = 0; @Override public void create() { _sourceTexture = new Texture(Gdx.files.internal("data/character.png")); } . . } 

在渲染屏幕期间,如果用户触摸屏幕,我抓住触摸的坐标,然后使用这些来渲染角色图像。

 @Override public void render(float delta) { if (Gdx.input.justTouched()) { x = Gdx.input.getX(); y = Gdx.input.getY(); } super.getGame().batch.draw(_sourceTexture, x, y); } 

问题是从左下角开始绘制图像的坐标(如LibGDX Wiki中所述),触摸输入的坐标从左上角开始。 所以我遇到的问题是我点击右下方,它将图像移动到右上角。 我的坐标可能是X 675 Y 13,触摸时它将靠近屏幕顶部。 但是角色显示在底部,因为坐标从左下角开始。

为什么是这样的? 为什么坐标系反转? 我使用错误的对象来确定这个吗?

要检测冲突,我使用camera.unproject(vector3) 。 我将vector3设置为:

 x = Gdx.input.getX(); y = Gdx.input.getY(); z=0; 

现在我在camera.unproject(vector3)传递此向量。 使用此向量的xy来绘制角色。

你做得对。 Libgdx通常以“原生”格式提供坐标系统(在本例中为原生触摸屏坐标和默认的OpenGL坐标)。 这不会创建任何一致性,但它确实意味着库不必介入您和其他所有内容。 大多数OpenGL游戏都使用相机将相对任意的“世界”坐标映射到屏幕上,因此世界/游戏坐标通常与屏幕坐标非常不同(因此不可能保持一致性)。 请参阅更改LibGDX中的坐标系(Java)

有两种方法可以解决这个问题。 一个是转换你的触摸坐标。 另一种是使用不同的相机(不同的投影)。

修复触摸坐标 ,只需从屏幕高度中减去y即可。 这有点像黑客。 更一般地说,您希望从屏幕“退出”到世界中(请参阅Camera.unproject()变体 )。 这可能是最简单的。

或者,要修复相机,请参阅“ 更改LibGDX中的坐标系(Java) ”或libgdx论坛上的这篇文章 。 基本上你定义一个自定义相机,然后设置SpriteBatch使用它而不是默认值:

 // Create a full-screen camera: camera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); // Set it to an orthographic projection with "y down" (the first boolean parameter) camera.setToOrtho(true, Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); camera.update(); // Create a full screen sprite renderer and use the above camera batch = new SpriteBatch(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); batch.setProjectionMatrix(camera.combined); 

固定相机工作时,它“向上游游泳”了一下。 您将遇到其他渲染器( ShapeRenderer ,字体渲染器等),这些渲染器也会默认为“错误”的相机,需要修复。

我有同样的问题,我只是这样做。

 public boolean touchDown(int screenX, int screenY, int pointer, int button) { screenY = (int) (gheight - screenY); return true; } 

每次你想从用户那里获取输入时都不要使用Gdx.input.getY(); 而是使用(Gdx.graphics.getHeight() – Gdx.input.getY())对我有用。

以下链接讨论了此问题。

将世界空间中的给定坐标投影到屏幕坐标。

您需要在project(Vector3 worldCoords)类中使用方法project(Vector3 worldCoords)

 private Camera camera; ............ @Override public boolean touchDown(int screenX, int screenY, int pointer, int button) { 

创建向量的实例并使用输入事件处理程序的坐标对其进行初始化。

  Vector3 worldCoors = new Vector3(screenX, screenY, 0); 

将世界空间中给出的worldCoors投影到屏幕坐标。

  camera.project(worldCoors); 

使用投影坐标。

  world.hitPoint((int) worldCoors.x, (int) worldCoors.y); OnTouch(); return true; }