在 Java Libgdx 中正确使用 unProject

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18554126/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 09:00:27  来源:igfitidea点击:

Using unProject correctly in Java Libgdx

javaopengllibgdx

提问by Chimpanse

I want to make a button clickable, but it isn't working - it seems like I need to use unproject()but I can't figure out how. The code in question is:

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

采纳答案by noone

In general you use camera.unproject(Vector)to transform your screen coordinates from a click or touch to your gameworld. This is needed because the origin is not necessarily the same and using the camera you can also zoom in and out, move around, rotate and so on. Unprojecting will take care of all of that and give you your game world coordinate matching the pointers position.

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

In your example it would go like this:

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

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

Having this said you should actually not do this UI task manually. Libgdx has also some shipped UI functionality which is called a Stage(see this). There are lots of widgets already available (see this). They use skins (you can get a basic one from here, you need all the uiskin.* files). They automatically forward inputevents to the socalled Actors, e.g. a button, and you just need to implement handling of those events.

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

回答by Kumar Saurabh

when ever u need a touch point from user and to convert those touchpoints to camera u need to unproject them to camera coordinates by camera coordinates

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

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

回答by Paras Mittal

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

回答by laubed

with camera.unproject(Vector3); you can translate screen coordinates to game world coordinates.

使用 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.

In addition to that it is best practice to define a tmpVector as a field an Instantiate a Vector3 object only once. You can then do the same with the .set() method.

除此之外,最佳实践是将 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.

Therefore you reduce object creation and remove unnecessary GC calls which lead to microlag.

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