libgdx coordinate system differences between rendering and touch input

前端 未结 4 1665
我在风中等你
我在风中等你 2021-02-08 01:50

I have a screen (BaseScreen implements the Screen interface) that renders a PNG image. On click of the screen, it moves the character to the position touched (for testing purpo

相关标签:
4条回答
  • 2021-02-08 02:40

    To detect collision I use camera.unproject(vector3). I set vector3 as:

    x = Gdx.input.getX();     
    y = Gdx.input.getY();
    z=0;
    

    Now I pass this vector in camera.unproject(vector3). Use x and y of this vector to draw your character.

    0 讨论(0)
  • 2021-02-08 02:48

    I had same problem , i simply did this.

    public boolean touchDown(int screenX, int screenY, int pointer, int button) {
    
        screenY = (int) (gheight - screenY);
        return true;
    }
    

    and every time you want to take input from user dont use Gdx.input.getY(); instead use (Gdx.graphics.getHeight()-Gdx.input.getY()) that worked for me.

    0 讨论(0)
  • 2021-02-08 02:48

    The link below discusses this problem.

    Projects the given coords in world space to screen coordinates.

    You need to use the method project(Vector3 worldCoords) in class com.badlogic.gdx.graphics.Camera.

    private Camera camera;
    ............
    
    @Override
    public boolean touchDown(int screenX, int screenY, int pointer, int button) {
    

    Create an instance of the vector and initialize it with the coordinates of the input event handler.

        Vector3 worldCoors = new Vector3(screenX, screenY, 0);
    

    Projects the worldCoors given in world space to screen coordinates.

        camera.project(worldCoors);
    

    Use projected coordinates.

        world.hitPoint((int) worldCoors.x, (int) worldCoors.y);
    
        OnTouch();
    
        return true;
    }
    
    0 讨论(0)
  • 2021-02-08 02:52

    You're doing it right. Libgdx generally provides coordinate systems in their "native" format (in this case the native touch screen coordinates, and the default OpenGL coordinates). This doesn't create any consistency but it does mean the library doesn't have to get in between you and everything else. Most OpenGL games use a camera that maps relatively arbitrary "world" coordinates onto the screen, so the world/game coordinates are often very different from screen coordinates (so consistency is impossible). See Changing the Coordinate System in LibGDX (Java)

    There are two ways you can work around this. One is transform your touch coordinates. The other is to use a different camera (a different projection).

    To fix the touch coordinates, just subtract the y from the screen height. That's a bit of a hack. More generally you want to "unproject" from the screen into the world (see the Camera.unproject() variations). This is probably the easiest.

    Alternatively, to fix the camera see "Changing the Coordinate System in LibGDX (Java)", or this post on the libgdx forum. Basically you define a custom camera, and then set the SpriteBatch to use that instead of the default.:

    // Create a full-screen camera:
    camera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
    // Set it to an orthographic projection with "y down" (the first boolean parameter)
    camera.setToOrtho(true, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
    camera.update();
    
    // Create a full screen sprite renderer and use the above camera
    batch = new SpriteBatch(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
    batch.setProjectionMatrix(camera.combined);
    

    While fixing the camera works, it is "swimming upstream" a bit. You'll run into other renderers (ShapeRenderer, the font renderers, etc) that will also default to the "wrong" camera and need to be fixed up.

    0 讨论(0)
提交回复
热议问题