Pixels to dips, desktop and android

1.8k views Asked by At

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?

4

There are 4 answers

4
Tanmay Patil On

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

0
srikanth On

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

0
joecks On

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.

0
Daahrien On

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);