LibGDX Tutorial - Resolution independence (Common Problems 1)

If you have followed the tutorials until now, then you have already setup libGDX, you also have configured the game to be landscape and have the Android virtual buttons hidden. Then, what we did was to remove the badlogic logo and put in its place our own one. But some of you may have encountered a problem when doing so, and that's because you probably use a device with different resolution and therefore maybe the aspect ratio is different too.

  • Resolution is the number of distinct pixels in each dimension that can be displayed.
  • If we divide the number of pixels of X - axis by the the number of pixels of Y - axis then we get the aspect ratio of the device.|

In order to debug my games, i am using a mobile device with a resolution of 720 x 1280 pixels. Because the game we will create has landscape orientation we consider that the resolution of the device is 1280 x 720 pixels. If we make the division then we get an aspect ratio of 16 ÷ 9.

" Why are you using this exact device? "

First of all 1280 x 720 used to be the most common resolution amongst the android devices that people were using. Nowadays, devices with resolution of 1920 x 1080 are constantly and rapidly rising, thus i suggest that you use a device with a resolution of 1920 x 1080 for your future projects.

Even though there are certain techniques that you are bound to use in order to make your game available for every device, it's always better to develop it and debug it in the one with the most common resolution and aspect ratio. That's mostly because of the aspect ratio, but we will talk about that on the next tutorial. For now, lets just focus on how to achieve resolution independence.

Virtual resolution and libGDX camera

Instead of using pixels as a measurement unit, we are going to make up our own measurement unit that is virtual but will help us achieve our purpose. If we developed our game for devices only with a certain resolution, then, when someone else with a completely different device resolution and aspect ratio tried our game he would find out that everything is messed up. To solve this, the first step is to create everything based on our own virtual resolution.

Lets say we choose this virtual resolution to be 16 x 9. How to do that? LibGDX has a very convenient camera class that does exactly that and many more. We will learn how to use the camera class on the next How To tutorial, but for now lets just understand the logic once and for all. We consider that every device has this virtual resolution now. This means that every time, we do a simple transformation from the device's resolution to our own virtual one.

Do you remember our problem? We wanted to place our gamengineering logo on the first screen. This time we will place the logo but first we have to tell the device that the width and the height of the logo must be 16 x 9.

Why? "

Because we considered every device to have OUR virtual resolution (and as we said we will achieve that by using the libGDX camera class). This means that the logo will fit in every screen perfectly.

The original logo is a 1280 x 720 image. If the device originally has 1280 x 720 resolution then each unit of our own measurement unit equals to:

1280 ÷ 16 = 80 pixels
720 ÷ 9 = 80 pixels

If the device originally has 1920 x 1080 resolution then each unit of our own measurement unit equals to:

1920 ÷ 16 = 120 pixels
1080 ÷ 9 = 120 pixels

In the first case, if we wanted to place a small image somewhere in our screen, then we would have to define the point (x,y), for example (10,4) and how big we want the image to be, for example (5,5). So how big will it be in pixels? Simply, 5 x 80 = 400 pixels width, and 5 x 80 = 400 pixels height. In which pixel of the screen will it be? In the 10 x 80 = 800th pixel on X - xis and 4 x 80 = 320th pixel on Y - axis.

In the second case, how big will it be in pixels? Simply, 5 x 120 = 600 pixels width, and 5 x 120 = 600 pixels height. In which pixel of the screen will it be? In the 10 x 120 = 1200th pixel on X -axis and 4 x 120 = 480th pixel on Y - axis.

Problem solved, now every time a device with a different resolution tries to run our game the logo will fit on the screen perfectly.

There is one more problem though. If the device has bigger or lesser resolution then our logo has to be stretched or to be downsized. And we don't want that do we?

Graphic filters and different sets of graphics

In order to solve the problem that came up we have to do 2 things:

  1. Filter our graphics. (can we do that in all devices though?)
  2. Use different sets of graphics (can we do that for all devices though?)

Filtering

You have to filter the graphics if they are downsized or stretched in order for them to not look that bad. There is a limit to that though. We can use a 100 x 100 image, stretch it to be 200 x 200 and then filter it and get a very good result, but we can't stretch it to 1000 x 1000, then filter it and expect to get good results. The same goes for when an image is downsized.

Filtering also is a process that needs more " power " and if you overdo it, then the game could have bad performance. There are plenty types of filtering. The ones that lead to a better visual result could also lead to bad performance and the others that don't, could lead to " not that good " visual results. The filtering of the graphics used to be a more complicated problem though. Nowadays the majority of the devices can handle the best types of filtering (for example tri - linear filtering) with the best visual results and still maintain a great performance.

LibGDX has these filters implemented and we are going to use them in the next How To tutorial.

Sets of graphics

As i told you before, there are certain limitations to graphics filtering. To give the final touch to the resolution independence problem we can use different graphics sets. If we use 1 file that contains all the graphics for EVERY device's resolution then people would need to download a 20000 giga byte game from Play Store and you probably don't want that.

From now on it is your own choice. You have to create sets of graphics for some popular resolutions and force the devices with other resolutions to use the file that is closest to their own resolution. After that, you filter those downsized or stretched graphics and the problem is solved.

Sum up of resolution independence problem

To solve the resolution independence problem we used a combination of 3 techniques:

  1. Virtual resolution.
  2. Graphics filtering.
  3. Different sets of graphics.

" Is that all? "

Unfortunately it's not. We have one last problem to first understand and then solve and this is the aspect ratio independence problem that goes hand - to - hand with the resolution independence problem.  The problem is that when we made the choice of using a 16 x 9 as virtual resolution we also made a choice of the aspect ratio 16 ÷ 9. 

Everything we discussed until now will work great only for the devices that have the same aspect ratio as ours. But what if a device with a different aspect ratio, for example 4 ÷ 3 tries to run our game. 

If the device originally has 4000 x 3000 resolution (just image it :P)  then each unit of our own measurement unit equals to:

4000 ÷ 16 = 250 pixels
3000 ÷ 9 ≃ 333.33 pixels

The original aspect ratio of the logo though was 16 ÷ 9, because it was on purpose created to fit only these types of screens. Now, if we tell the device that the width and the height of the logo must be 16 x 9, it will fit the screen perfectly but it would be more stretched up on the Y - axis and would look awful. To give you an example look at the following Black Dodger images.

Normal Black Dodger
Black Dodger normal 16:9
Stretched Black Dodger
Black Dodger stretched 4:3


The first one is the original image made for devices with aspect ratio 16:9 and the second one is what could happen if a device with aspect ratio of 4:3 tries to run our game. See how stretched Black Dodger is on Y- axis? Just look at his head.

Don't worry if you cannot fully understand this problem because  next time we will solve the aspect ratio independence problem.


Feel free to ask any questions in the comments below! 

Comments

  1. That was probably one of the most understandable explanations of the problem. Extend viewport though, only expands the world to 1 direction. So how can you say that we can extend it on more?

    ReplyDelete
    Replies
    1. Fair question! The point of this tutorial was to understand the logic of the problem and of the presented solutions. You are right about extend viewport. You can always create your own custom viewport though, according to your needs. That's exactly what we did in this tutorial;

      https://gamengineering.blogspot.com/2018/07/libgdx-tutorial-resolution-aspect-ratio-independence-viewports-camera.html

      because extend viewport didn't suit us.

      Delete

Post a Comment