Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

How do I make my libGDX game resolution/density independent? Is there a way to specify image sizes as "absolute" regardless of the underlying density?

I'm making a very simple kids game; just a bunch of sprites displayed on-screen, and some text for menus (options menu primarily). What I want to know is: how do I make my sprites/fonts resolution independent? (I have wrapped them in my own classes to make things easier.)

Since it's a simple kids game, I don't need to worry about the "playable area" of the game; I want to use as much of the screen space as possible.

What I'm doing right now, which seems super incorrect, is to simply create images suitable for large resolutions, and then scale down (or rarely, up) to fit the screen size. This seems to work okay (in the desktop version), even with linear mapping on my textures, but the smaller resolutions look ugly.

Also, this seems to fly in the face of Android's "device independent pixels" (DPs). Or maybe I'm missing something and libGDX already takes care of this somehow?

What's the best way to tackle this? I found this link; is this a good way of solving the problem?: http://www.dandeliongamestudio.com/2011/09/12/android-fragmentation-density-independent-pixel-dip/

It mentions how to control the images, but it doesn't mention how to specify font/image sizes regardless of density.

share|improve this question
    
Possibly related? gamedev.stackexchange.com/questions/34/… –  thedaian Feb 28 '12 at 3:54
    
@thedaian not quite. That's about resolution; I'm more concerned about the interplay between density and resolution. –  ashes999 Feb 28 '12 at 15:11
add comment

3 Answers 3

I believe Android's "device independent pixels" are just a measuring stick for classifying devices, and aren't actually available as renderable pixels. So you're not missing out on any magical DPI-solving infrastructure. As far as I understand the state of the art here, you have discovered all the options. There are two basic approaches for dealing with different devices:

  1. Scale pre-existing images to match the actual device DPI.
  2. Choose from a variety of pre-scaled images at run-time based on the DPI.

Of course, you can do some mix of the two (picking a roughly accurate image and then scaling it), or use different approaches for different elements of your UI (e.g., pre-existing images for fonts/text, and dynamic scaling for gameplay sprites).

What your specific game is trying to do can really make a difference in which approach makes more sense. For example, if you've got an on-screen menu you'll want to make sure the buttons are some reasonable multiple of a finger-tip size (so the button is always easy to hit, but isn't larger than necessary on big devices like tablets). Alternatively, if you're trying to build a puzzle game where you want to make sure the entire puzzle is visible at once, you'll need to scale the elements to fit on the screen (for example, with a tic-tac-toe game perhaps you'd like each element to use roughly 1/3 of the screen).

I think for things like fonts that have a lot of fine detail you'll want to have a variety of pre-rendered images with text, and then pick the best-matching. So buttons might change their relative shape/size from one device to another, but will generally always look nice.

Check out Mario Zerchner's Beginning Android Games for some discussion of the problems and some solutions. Note that Mario is the author of libGDX, so the book's approach mirrors the libGDX one (note they're not one-to-one, the book covers writing a library similar to libGDX, but not libGDX itself).

share|improve this answer
    
Even if I select from pre-made image collections based on DPI, I don't see how I can guarantee that "this sprite MUST display as 64x64." –  ashes999 Feb 29 '12 at 17:35
1  
I was assuming you set your OpenGL camera to match the physical display, so 1 OpenGL pixel maps to 1 display pixel. At that point a 64x64 image will show up as 64x64 on the screen. As Rudy_TM points out, you can mess with the camera mapping to get whole-screen scaling. –  P.T. Feb 29 '12 at 18:14
    
Okay, this looks like the "secret sauce" I was after. I'll check and let you know, thanks. –  ashes999 Feb 29 '12 at 18:26
add comment

To achieve this in libgdx, you can use the "orthographicCamera" there you asign the size that you wat to use, and in every resolution you may see all your images scaled to that size (i use the 800X480 because its the larger screen in Android) and it works good :)

public class GameStage extends Stage 
{ 
     public GameStage(float width, float height, boolean stretch) 
     { 
          this.camera = new OrthographicCamera(800, 480);
          this.camera.position.set(800/2, 480/2, 0f); 
     } 
}
share|improve this answer
    
Can I get a code sample, please? –  ashes999 Feb 29 '12 at 1:12
    
Thats the code, and you create a class that implements the Screen interface, in the constructor you build your stage, and in the render method, you put stage.draw(). If you dont want to use Stages, you may declare a variable in the Screen implemented class of type Camera, and do the same thing as in Stage, but in the render method you apply an update to the camera. –  Rudy_TM Feb 29 '12 at 15:33
    
Okay, thanks, I'll try it out. –  ashes999 Feb 29 '12 at 17:34
    
This actually works pretty well. –  you786 Sep 26 '13 at 17:35
add comment

Since you can read the device density and render fonts during runtime in libgdx, I use this solution to achieve a density independent font size:

float densityIndependentSize = origFontSize * Gdx.graphics.getDensity();
int fontSize = Math.round(densityIndependentSize );
BitmapFont font = generator.generateFont(fontSize );
share|improve this answer
    
My discussion is about images as well as fonts. +1 for dynamic font rendering though (I do this already). –  ashes999 Oct 18 '13 at 21:28
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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