5

I am using Libgdx to code an android game and as you may know, many screen resolutions cause some problems if done incorrectly. So I am trying to use this DP unit rather than pixels.

However, I have this method here:

public static float pixelToDP(float dp){
    return dp * Gdx.graphics.getDensity();
}

the Gdx.graphics.getDensity() method actually gets the SCALE, so it's already done for me.

Now the problem, libgdx is cross platform which is good for testing. When I launch this on my S4 which has a resolution of 1920x1080 with a dpi of a whopping 480, opposed to my terrible and overpriced laptop which has 1366x768 @ 92dpi it is placed exactly where I want it. On desktop it is way off, a good few hundred pixels on the X and Y axis.

Is this due to the fact my screen dpi is measured @92dpi, the resolution is a lot lower and the actual game is not fullscreen on the desktop?

Here is the code for drawing the object:

table.setPosition(MathHelper.pixelToDP(150), MathHelper.pixelToDP(200));

In order to get it perfect on desktop I have to do:

table.setPosition(MathHelper.pixelToDP(480), MathHelper.pixelToDP(700));

Which is not even visible on my phone, since the scale is actually 3x, which puts it a good 200 pixels off the screen on the Y axis.

Is there a way around this? Or am I basically going to have to deal with doing platform checks and different blocks of code?

Possible solution:

So I changed my dp conversion method, if I was to do 100 * 0.5 it would return a new value of 50 but in reality I want the orignal value of 100 + 100 * 0.5.

Not sure if this is a proper fix or not but regardless by table is drew in the exact same place on both laptop and phone:

public static float pixelToDP(float dp){
    if(Gdx.graphics.getDensity() < 1)
        return dp + dp * Gdx.graphics.getDensity();
    return dp * Gdx.graphics.getDensity();

Is this just a cheap fix or is this pretty much how it should be done?

Gibbo
  • 630
  • 1
  • 8
  • 22

4 Answers4

4

Usage of density independent pixels implies that the physical size of the table on all screens should be same. Since your laptop screen is (physically) much bigger, you would see the table to be lot smaller than expected.

I would suggest an alternative approach of placing objects in fractions of size. e.g. 30% of width or 45% of height.

To implement this, just assume a stage resolution and place objects as you like then change viewport in resize method such that you get full view. Hope it helps.

For more, https://code.google.com/p/libgdx-users/wiki/AspectRatio

Tanmay Patil
  • 6,882
  • 2
  • 25
  • 45
  • Ah right ok, my table is actually different in size between both devices, since my phone has more pixels the button looks significantly smaller so I load a spire that is larger. – Gibbo Dec 13 '13 at 17:08
  • Exactly. But instead of loading different sprites, you could simply change viewport to take care of scaling. But it's a matter of choice anyways. Good luck. – Tanmay Patil Dec 13 '13 at 17:31
  • I am going to try the viewport method, I really don't want to create different res spprites, time consuming. Updated op with a possible fix, let me know what you think – Gibbo Dec 13 '13 at 17:34
  • If you try to test it on a third device, say a low resolution android phone, your hard earned calibration might fail. :D I won't recommend using it. – Tanmay Patil Dec 13 '13 at 17:43
2

The best approach for this is to manipulate the density based on the execution target.

So what I usually do is to store the density in a field in a singleton, and set it based on the scenario:

public class Game {

 public static float density;

  public static initDensity(){
    if (GDX.app.getTarget() == 0){
      density = 2.0f;
    }else {
       density = GDX.graphics.getDensity();
    }
  }

  public float toPixel(float dip){
    return dip * density;
  }
} 

with this approach you can "simulate" a more dense screen then you actually have, and by using properties in your run config like -Ddensity=2 and System.getPropery("density") you can vary the screens you like to simulate.

joecks
  • 4,539
  • 37
  • 48
1

One approach is having a fixed viewport size. Create your camera for example 1366x768 and place all your objects using that coordinate. Then the camera will fill the whole screen of every other resolution.

cam = new OrthographicCamera(1366, 768);
Daahrien
  • 10,190
  • 6
  • 39
  • 71
0

try seeing few tutorials....I personally think it is best to deal with pixels and using the camera will help you a lot, check this link once

getting different screen resolutions

Community
  • 1
  • 1
srikanth
  • 301
  • 3
  • 14