java 渲染和触摸输入之间的 libgdx 坐标系差异
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16514152/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
libgdx coordinate system differences between rendering and touch input
提问by Brian Mains
I have a screen (BaseScreen implements the Screen interface) that renders a PNG image. On click of the screen, it moves the character to the position touched (for testing purposes).
我有一个呈现 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"));
}
.
.
}
During rendering of the screen, if the user touched the screen, I grab the coordinates of the touch, and then use these to render the character image.
在渲染屏幕时,如果用户触摸屏幕,我会抓取触摸的坐标,然后使用这些坐标来渲染字符图像。
@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);
}
The issue is the coordinates for drawing the image start from the bottom left position (as noted in the LibGDX Wiki) and the coordinates for the touch input starts from the upper left corner. So the issue I'm having is that I click on the bottom right, it moves the image to the top right. My coordinates may be X 675 Y 13, which on touch would be near the top of the screen. But the character shows at the bottom, since the coordinates start from the bottom left.
问题是绘制图像的坐标从左下角开始(如 LibGDX Wiki 中所述),而触摸输入的坐标从左上角开始。所以我遇到的问题是我点击右下角,它将图像移动到右上角。我的坐标可能是 X 675 Y 13,触摸时会靠近屏幕顶部。但是字符显示在底部,因为坐标从左下角开始。
Why is what? Why are the coordinate systems reversed? Am I using the wrong objects to determine this?
为什么是什么?为什么坐标系颠倒了?我是否使用错误的对象来确定这一点?
回答by Pranav008
To detect collision I use camera.unproject(vector3)
. I set vector3
as:
为了检测碰撞,我使用camera.unproject(vector3)
. 我设置vector3
为:
x = Gdx.input.getX();
y = Gdx.input.getY();
z=0;
Now I pass this vector in camera.unproject(vector3)
. Use x
and y
of this vector to draw your character.
现在我将这个向量传入camera.unproject(vector3)
. 使用x
和y
这个载体来绘制你的性格。
回答by P.T.
You're doing it right. Libgdx generally provides coordinate systems in their "native" format (in this case the native touch screen coordinates, and the default OpenGL coordinates). This doesn't create any consistency but it does mean the library doesn't have to get in between you and everything else. Most OpenGL games use a camera that maps relatively arbitrary "world" coordinates onto the screen, so the world/game coordinates are often very different from screen coordinates (so consistency is impossible). See Changing the Coordinate System in LibGDX (Java)
你做得对。Libgdx 通常以它们的“原生”格式提供坐标系统(在这种情况下是原生触摸屏坐标,以及默认的 OpenGL 坐标)。这不会产生任何一致性,但它确实意味着库不必介于您和其他一切之间。大多数 OpenGL 游戏使用相机将相对任意的“世界”坐标映射到屏幕上,因此世界/游戏坐标通常与屏幕坐标非常不同(因此不可能保持一致)。请参阅在 LibGDX (Java) 中更改坐标系
There are two ways you can work around this. One is transform your touch coordinates. The other is to use a different camera (a different projection).
有两种方法可以解决此问题。一种是转换您的触摸坐标。另一种是使用不同的相机(不同的投影)。
To fix the touch coordinates, just subtract the y from the screen height. That's a bit of a hack. More generally you want to "unproject" from the screen into the world (see the
Camera.unproject()
variations). This is probably the easiest.
要修复触摸坐标,只需从屏幕高度中减去 y。这有点骇人听闻。更一般地,您希望从屏幕“取消投影”到世界中(请参阅
Camera.unproject()
变体)。这可能是最简单的。
Alternatively, to fix the camerasee "Changing the Coordinate System in LibGDX (Java)", or this post on the libgdx forum. Basically you define a custom camera, and then set the SpriteBatch
to use that instead of the default.:
或者,要修复相机,请参阅“更改 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);
While fixing the camera works, it is "swimming upstream" a bit. You'll run into other renderers (ShapeRenderer
, the font renderers, etc) that will also default to the "wrong" camera and need to be fixed up.
在修复相机工作的同时,它有点“逆流而上”。您会遇到其他渲染器(ShapeRenderer
字体渲染器等),这些渲染器也将默认使用“错误”的相机,需要进行修复。
回答by geekydhaval
I had same problem , i simply did this.
我有同样的问题,我只是这样做了。
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
screenY = (int) (gheight - screenY);
return true;
}
and every time you want to take input from user dont use Gdx.input.getY(); instead use (Gdx.graphics.getHeight()-Gdx.input.getY()) that worked for me.
并且每次你想从用户那里获取输入时不要使用 Gdx.input.getY(); 而是使用对我有用的 (Gdx.graphics.getHeight()-Gdx.input.getY()) 。
回答by Andrey Rogachev
The link below discusses this problem.
下面的链接讨论了这个问题。
Projects the given coords in world space to screen coordinates.
You need to use the method project(Vector3 worldCoords)
in class com.badlogic.gdx.graphics.Camera
.
您需要使用project(Vector3 worldCoords)
class 中的方法com.badlogic.gdx.graphics.Camera
。
private Camera camera;
............
@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
Create an instance of the vector and initialize it with the coordinates of the input event handler.
创建向量的实例并使用输入事件处理程序的坐标对其进行初始化。
Vector3 worldCoors = new Vector3(screenX, screenY, 0);
Projects the worldCoors given in world space to screen coordinates.
将世界空间中给出的 worldCoors 投影到屏幕坐标。
camera.project(worldCoors);
Use projected coordinates.
使用投影坐标。
world.hitPoint((int) worldCoors.x, (int) worldCoors.y);
OnTouch();
return true;
}