Resolution independent positioning

Started by
11 comments, last by futlib 13 years, 2 months ago
Hi,

I'm working on an Android game (I don't think the issue is Android-only though) and I want to support all available resolutions and screen sizes. I studied the <a href="http://developer.android.com/guide/practices/screens_support.html">dev guide</a> and saved my background images in multiple resolutions:

- 240x432 (ldpi)
- 320x480 (mdpi)
- 480x854 (hdpi)

These resolutions have different aspect ratios. Furthermore, at each density level, there are more resolutions, also with different aspect ratios.

I solved that problem by simply centering my backgrounds. As long as I make sure that the relevant areas are visible on each device, it works fine.

However, now I want to position elements on specific spots of the image, which I am unable to achieve with my current approach. I could hard code positions for each resolution, but there has to be a better solution. Density independent pixels don't do the trick because of the different aspect ratios.

How do/would you approach this?
Advertisement
You could try homogenous coordinates, I started with these on iPad and thought it would make life easier going down to iPhone 4 / iPhone / iPod etc.

In the end I used a half and half approach of homogenous coordinates and actual pixel size/positions.
One way to do it to use border relative positioning. I place my gui by using the following convention:

x coord:
=0 => center at parent container
<0 => place right border of element abs(x) pixel away from right border of parent container
>0 => place left border of element abs(x) pixel away from left border of parent container

y coord: like x coord

My gui is represented by a tree of containers, where the root is the screen and the leafs are the widgets like buttons etc.
Thanks for your replies, but I'm not really sure I understand either of your approaches, sounds quite challenging :(

A colleague of mine just came up with an, in my opinion, surprisingly simple solution: Since I center the background, he said I should just draw my elements relative to the center of the screen. Like in a typical OpenGL coordinate system, as opposed to those normally used in 2D graphics. I cannot find any problem with this approach, is that common for this kind of thing? Or would you perhaps argue that the whole centering-the-background-thing isn't really a good idea in the first place?
It depends on how your game works. I mean that changing the resolution should not make the game easier / heavier, or else balancing would become nearly impossible. Especially things like comparing high-scores and game centers will be meaningless.

Different aspect ratios may be handled by fitting the desired view into the available screen dimensions. If the aspect ratio doesn't match, then filling the gap (or perhaps gaps if two sided) with a background not counting to the gameplay. Positioning should be done resolution independent anyway. Thinking of a camera that looks into the scene, where the camera has a view size in some virtual world co-ordinates. Then this view is sampled accordingly to the given resolution, making up the pixels the player sees. Moving objects then means to move them in units of said virtual world, not in units of pixels. You can snap to real pixel positions just for the rendering.

And supporting low and high resolution images is also possible; just hide this in the resource management. Then only rendering really needs to know the resolution.

A "typical OpenGL co-ordinate system" has its origin in the center of the screen, that's true. However, it also has an extended view that is decoupled from pixel sampling. The projection matrix will map the virtual world sized view onto the normalized view volume. So this is an example that matches what I've written above.
Thanks haegarr, calculating the positions sounds like the most natural approach, guess I'll do that.

By now, I'm really confused by the whole issue of resolution and aspect ratio independence. I just thought that I could eliminate the problems raised by different ratios between resolutions by just using the same size and then scaling down. For this, I calculated a "maximum screen area" and a "minimum screen area".

The maximum screen area will be the maximum of what can be seen on any device, and hence the size of background images. I calculated this to be 480x864.

Then I've pondered a bit over the numbers and came to the conclusion that the minimum screen area will be 480x640 respectively, to support all resolutions. If I make sure that all relevant parts of the background are shown within this area of the center of the background and that all elements are positioned within it, my game should work on all available resolutions.

These numbers will be scaled down for mdpi and ldpi.

Does this sound like a reasonable approach to you?

Furthermore, are the following really all possible screen sizes of Android devices?
  • QVGA (240x320)
  • WQVGA400 (240x400)
  • WQVGA432 (240x432)
  • HVGA (320x480)
  • WVGA800 (480x800)
  • WVGA854 (480x854)
perhaps you should try
smartly using matrices
transforming nicely

perhaps you should try
smartly using matrices
transforming nicely


When you've got a game to ship and the client breathing down your neck - BODGE IT AND SCARPER.

Do it correctly on the next project :)
Well if I was doing it then I'd create a simple scale coordinate system. Get the resolution size and go from there(ex. Divide to find the middle). Then you can set x and y scale to 0.5 and no matter the size, it will always be in the center.
Another general purpose "surprisingly easy" approach is to just add black bars as needed, and render at your own preferred size.

This works nicely even on windowed environments, not just full screen. If the display window is too wide, draw it as maximum height and put black bars on the sides. If it is too tall, draw at maximum width with bars above and below. Keep your game in a floating point 0.0 to 1.0 size so you'll still be able to access each individual pixel for any size screen currently imaginable.

This topic is closed to new replies.

Advertisement