2013-09-01 43 views
13

我想使按钮可点击,但它不工作 - 它似乎我需要使用unproject(),但我不知道如何。有问题的代码是:在Java中正确使用unproject libgdx

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(); 
     } 
    } 
} 
+0

屏幕坐标(0,0)可能位于左上角,但相机的坐标(0,0)位于左下角。如果使用Gdx.input.getY()* - 1,会发生什么? – Ryan

回答

11

一般来说,你使用camera.unproject(Vector)改变你的屏幕来自点击或触摸到你的游戏世界坐标。这是必要的,因为原点不一定相同,使用相机也可以放大,缩小,移动,旋转等。 Unprojecting会处理所有这些,并为您提供与指针位置匹配的游戏世界坐标。

在你的榜样,将是这样的:

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

有了这个说你其实不需要手动执行此UI任务。 Libgdx还有一些已发布的U​​I功能,称为Stage(请参阅this)。有很多可用的小部件(请参阅this)。他们使用皮肤(你可以从here获得基本的皮肤,你需要所有的uiskin。*文件)。他们自动地向所谓的Actors转发事件,例如,一个按钮,你只需要实现这些事件的处理。当过u需要从用户和这些接触点到相机ü需要unproject它们转换触摸点的相机通过相机坐标

+2

正如我的答案中所述,在触摸时在每一帧上初始化一个新的Vector3对象会引入大量开销。 GC周期尤为重要,尤其是对时间要求严格的应用程序,如游戏(移动设备甚至更糟;而libgdx也针对移动设备) – laubed

+0

您也可以使用Pools来解决初始化新Vector3的问题。 – bazola

0

坐标

camera.unproject(touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0)); 
1
@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(); 
    } 
    } 
    } 
3

与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. 

因此,您可以减少对象的创建并删除导致微滞后的不必要的GC调用。