在Java Libgdx中正确使用unProject

我想要一个按钮可点击,但它不工作 – 似乎我需要使用unproject()但我无法弄清楚如何。 有问题的代码是:

 Texture playButtonImage; SpriteBatch batch; ClickListener clickListener; Rectangle playButtonRectangle; Vector2 touchPos; OrthographicCamera camera; @Override public void show() { playButtonImage = new Texture(Gdx.files.internal("PlayButton.png")); camera = new OrthographicCamera(); camera.setToOrtho(false, 800, 480); batch = new SpriteBatch(); playButtonRectangle = new Rectangle(); playButtonRectangle.x = 400; playButtonRectangle.y = 250; playButtonRectangle.width = 128; playButtonRectangle.height = 64; } @Override public void render(float delta) { Gdx.gl.glClearColor(0, 0, 0.2f, 1); Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT); camera.update(); batch.setProjectionMatrix(camera.combined); batch.begin(); batch.draw(playButtonImage, playButtonRectangle.x, playButtonRectangle.y); batch.end(); if (Gdx.input.isTouched()) { Vector2 touchPos = new Vector2(); touchPos.set(Gdx.input.getX(), Gdx.input.getY()); if (playButtonRectangle.contains(touchPos)) { batch.begin(); batch.draw(playButtonImage, 1, 1); batch.end(); } } } 

通常,您使用camera.unproject(Vector)将屏幕坐标从点击或触摸转换为您的游戏世界。 这是必需的,因为原点不一定相同,使用相机你也可以放大,移动,旋转等等。 Unprojecting将负责所有这些并为您提供与指针位置匹配的游戏世界坐标。

在你的例子中,它会像这样:

 Vector3 touchPos = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0); camera.unproject(touchPos); 

有了这个说你实际上不应该手动执行这个UI任务。 Libgdx还有一些运行的UIfunction,称为Stage (见此)。 已经有很多小部件可用(见这个 )。 他们使用皮肤(你可以从这里得到一个基本的,你需要所有的uiskin。*文件)。 它们会自动将inputevents转发给所谓的Actors ,例如按钮,您只需要实现对这些事件的处理。

with camera.unproject(Vector3); 您可以将屏幕坐标转换为游戏世界坐标。

 Vector3 tmpCoords = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0); camera.unproject(tmpCoords); tmpCoords.x //is now the touched X coordinate in the game world coordinate system tmpCoords.y //is now the touched Y coordinate in the game world coordinate system. 

除此之外,最佳做法是将tmpVector定义为字段,仅实例化Vector3对象一次。 然后,您可以使用.set()方法执行相同的操作。

 tmpCoords.set(Gdx.input.getX(), Gdx.input.getY(), 0); camera.unproject(tmpCoords); tmpCoords.x //is now the touched X coordinate in the game world coordinate system tmpCoords.y //is now the touched Y coordinate in the game world coordinate system. 

因此,您减少了对象创建并删除了导致microlag的不必要的GC调用。

 @Override public void render(float delta) { Gdx.gl.glClearColor(0, 0, 0.2f, 1); Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT); camera.update(); batch.setProjectionMatrix(camera.combined); batch.begin(); batch.draw(playButtonImage, playButtonRectangle.x, playButtonRectangle.y); batch.end(); if (Gdx.input.isTouched()) { Vector3 touchPos = new Vector3(); touchPos.set(Gdx.input.getX(), Gdx.input.getY(),0); camera.unproject(touchPos); if (playButtonRectangle.contains(touchPos.x, touchPos.y)) { batch.begin(); batch.draw(playButtonImage, 1, 1); batch.end(); } } } 

当你需要用户的触摸点并将这些接触点转换为摄像机时,你需要通过摄像机坐标将它们取消投影到摄像机坐标

 camera.unproject(touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0));