7
\$\begingroup\$

I am using the LibGdx framework and have an issue.

Currently, I am creating a game in a resolution of 480 x 320 and using 'GL20' to remove the restriction of that dreaded 'power of two' error.

It works really well, but only in desktop and phones whose screen sizes are the same. But when I try it to a phone with a resolution of 320 x 240, I can only see a small part of the screen and the screen calculations that I made for touch events are now incorrect.

Is there any way to make it work the same as in the desktop version? Like for example, even on the 320x240 phone, the resolution of the game is still at 480x320.

\$\endgroup\$
3
  • \$\begingroup\$ See this: stackoverflow.com/questions/9198932/… \$\endgroup\$
    – nathan
    Feb 13, 2014 at 10:28
  • \$\begingroup\$ what if I am not using GL10 and Stage2d? Can I still solve it? Or I have to rewrite my code to work with Scene2d and GL10? cause I'm currently using GL20 \$\endgroup\$
    – Don
    Feb 13, 2014 at 14:41
  • \$\begingroup\$ You can directly play with the camera i guess. \$\endgroup\$
    – nathan
    Feb 13, 2014 at 15:16

1 Answer 1

12
\$\begingroup\$

This is a problem pretty much everyone faces when getting into LibGDX. What you need to remember as you code is this: pixels are bad. Down with pixels.

Because you're using a camera object to determine how/where to draw your sprites on screen, you can set your game's world to use any units you want, and scale to each screen just by constructing the camera appropriately.

If you were to use a tile map to build your levels, I'd say use those tiles as your unit. Doesn't matter how you draw your levels, though -- make up a unit of measurement and stick to it. My screen (in landscape view) is 20 units (tiles, metres, character-heights, whatever) high, with the width scaled so that the tiles are square (ppu is pixels per unit):

// Always a screen height of 20 units;
// width depends on screen aspect ratio.
float height = 20;
float ppu = Gdx.graphics.getHeight() / height;
float width = Gdx.graphics.getWidth() / ppu;

So say you run it on a Full HD screen (1920x1080). If height = 20, then ppu = (1080 / 20) = 54. So width = (1920 / 54) = 35.55555... Your sprites will be automatically scaled (up) to fit that screen size.

On the smaller of the resolutions you mentioned? ppu = (240 / 20) = 12, so width = (320 / 12) = 26.66666... Your sprites will be automatically scaled (down, this time) to fit that screen too.

Then construct your camera using those values:

OrthographicCamera cam = new OrthographicCamera(width, height);
cam.position.set(width / 2, height / 2, 0);
cam.update();

width / 2 and height / 2 being the centre of the screen. If you're using your camera's combined matrix as the SpriteBatch's projection matrix -- batch.setProjectionMatrix(cam.combined) -- then it'll take care of screen resolution for you. And that's it.

Well, almost. You now need to define your Sprites and any other objects in your shiny new world coordinates. If your Sprite was 32 pixels high on your test 480x320 phone, its new height is 2. Don't change the TextureRegions -- they're still in pixels, since they're to do with your image file, not your world. Not at all confusing, right?

Now, if you want to translate from touch coordinates to in-game coordinates, you need to do a two-step conversion as explained here. First from screen coords to camera coords, then from camera coords to world coords:

// Vector2 touchV comes from your InputAdapter.touchDown()
cam.unproject(touchV);
float x = cam.position.x - cam.viewportWidth + touchV.x;
float y = cam.position.y - cam.viewportHeight + touchV.y;
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .