1
\$\begingroup\$

I've followed the advice in this post to handle world/screen coordinates, but I'm getting results I don't quite understand, as I'm not terribly good in math.

So, when I use this code:

SpriteBatch batch;
OrthographicCamera camera;
public static float width = 0, height = 0;

private void setupGraphics(SpriteBatch batch) {
    height = Constants.TILES_Y; // 20
    float pixelsPerUnit = Gdx.graphics.getHeight() / height;
    width = Gdx.graphics.getWidth() / pixelsPerUnit;
    Gdx.app.log("debug", "Width: " + width + " height: " + height + " ppu: " + pixelsPerUnit);
    camera = new OrthographicCamera(width, height);
    camera.position.set(0, 0 / 2, 0);
    camera.update();
    batch.setProjectionMatrix(camera.combined);
}

...the result looks like this - it seems that the view height is now 20 pixels, not 20 32x32 tiles:

buggy scene

However, when I add a multiplier to the height, like 16, the result looks like this, which is more like what I want:

correct scene

Here's the changed code:

    height = Constants.TILES_Y * Constants.TILES_MULTIPLIER; // 20 * 16

How would I modify the code to avoid having to supply the multiplier every time when I handle coordinates?

\$\endgroup\$
2
\$\begingroup\$

I would recommend re-reading the post as I don't think you completely understand why you're setting up an orthographic camera.

The whole point of this is to move away from pixels and move towards your own unit that doesn't depend on screen size. This way, everything can be properly scaled no matter the device.

it seems that the view height is now 20 pixels, not 20 32x32 tiles: - It's not 20 pixels, it's 20 units high. As I said above, these units are basically your new pixels that scale with the device's screen.

To answer your question, How would I modify the code to avoid having to supply the multiplier every time when I handle coordinates?, the answer is: you don't.

There are other things you can do though like have your tile rendering method take in a coordinate in "tiles coordinates" and then it multiplies by the tile size when you draw it.

Here's a little diagram I drew up quickly to explain it graphically. Infographic

\$\endgroup\$
0
\$\begingroup\$

Thanks to @MrIlliteracy for the extensive answer. I finally managed to wrap my head around this, I got it to work by setting the target width and height to 1 unit in my rendering method, like this:

public void render(SpriteBatch batch, Point location) {
    if(tileset != null) {
        batch.draw(
                tileset, // a libGDX Texture
                location.getX(), 
                location.getY(), 
                1, 1, // ADDED THESE
                (int)bottomLeft.getX() * Constants.TILE_DIM, 
                (int)bottomLeft.getY() * Constants.TILE_DIM, Constants.TILE_DIM, 
                Constants.TILE_DIM, 
                false, false // flips to get the right method overload
        );
    }
}

The program now looks like this:

game rendered correctly

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.