在Java Libgdx中正确使用unProject

时间:2013-09-01 00:34:59

标签: java opengl libgdx

我想点击一个按钮,但它不起作用 - 似乎我需要使用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();
        }
    }
}

4 个答案:

答案 0 :(得分:12)

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

在你的例子中它会是这样的:

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

有了这个说你实际上不应该手动执行这个UI任务。 Libgdx还提供了一些称为Stage的UI功能(参见this)。有许多小部件可用(参见this)。他们使用皮肤(你可以从here获得一个基本的皮肤,你需要所有的uiskin。*文件)。他们会自动将信息转发给所谓的Actors,例如一个按钮,你只需要实现这些事件的处理。

答案 1 :(得分:3)

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调用。

答案 2 :(得分: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 :(得分:0)

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

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