15

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

4 回答 4

12

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

在您的示例中,它将如下所示:

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

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

于 2013-09-01T05:57:08.597 回答
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 调用。

于 2015-03-27T20:26:50.187 回答
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();
    }
   }
   }
于 2013-09-01T09:23:53.793 回答
0

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

camera.unproject(touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0));
于 2013-09-01T09:18:43.830 回答