First, I don't know corona but hopefully this method will still help out.
I'm moving all my games to more of a zone based layout to handle screen real estate. With all the different iOS devices sizes now and considering the possible port to android you need to start moving away from pixel based. I still am doing somewhat of a merge between the two but leaning more towards using percentages.
The fact is though that there are really still only a couple of different sizes. So you don't have to worry about like a 1:10 screen or anything crazy like that. Most screens are somewhere between 4:3 and 16:9. Based on how your game operates and how you're using the real estate.
I went back in to my most recent game and looked at the zones I set up for it.
The most important zone here is the menu zone. The title and the footer can be reduced if the screen is more squarish and it will still look fine.
I'm in C and objectiveC, so all these zone sizes (percentages) I stick in a bunch of #define's. Then I can go back and tweak them as necessary and see the results without having to change any of my formulas. Every item that is getting placed also has an object.position.xyz that I stick the results in and draw from.
You take your screen width and height, this can be pixels or inches or whatever unit you use in your game, and multiply it by the percentages to get how many units each item or zone is. When centering items in a zone you're going to use a lot of * .5
s to find the placement location. Any percentage * screenUnitsHeight will be a conversion to units on the y axis. Here is my exact code for the placement of the title:
float screenTop = screenUnitsHeight/2.0; // /2.0 because the center is 0,0
float screenLeft = -screenUnitsWidth/2.0;
titleLocation = vec3Make(0.0, screenTop - screenUnitsHeight * .5 * ZONE_TITLE, -800.0);
Since zone title is 31% down from the top of the screen I can start there and move down half the height of the title. But then I also have to scale the title to fit in there. BTW, this title is a graphic and not text.
float titleMaxH = screenUnitsHeight * ZONE_H_MAX_TITLE;
float titleMaxW = screenUnitsWidth * ZONE_W_TITLE;
titleScale = min(titleMaxH / TITLE_SIZE_H, titleMaxW / TITLE_SIZE_W);
The title can't be bigger than what will fit in either the width or height, so I calculate each one and then use min()
to get the smallest of the two. In this case my ZONE_H_MAX_TITLE
is .4 to leave some boarder between the graphic and the edge of the zone.
Here you can see how things squish down to fit even on an iPad which is 4:3:
Since all the heights are percentages thing will always fit. The width ends up with extra space but it looks fine. In another game I want the main gameplay area to take precedence. In that case I have both a ZONE_MAX_W
and a ZONE_MIN_W
and use max()
and min()
functions to dial everything in.
You can see above that on the footer I had designed it for some overlap with the weasel and the title when on a new iPhone and I let things fall where they may on the iPad. The weasel and gear are each side justified and the company title is center justified. It's all just math.
Notice this, when you deign your main look that's going to be exactly what it is (even pixel for pixel) when on the device you designed it for. But then on other devices it should also look better. Test out each end of the spectrum and adjust things to make it look ok on that device, then go back to the main device and recheck that.
Your Map
Use the min()
function to make sure your map doesn't change aspect ratio no matter what the ratio of the device is. You might need to figure out what will be the background when it's shrunk to fit. Once you have the position and scale of the map you can use these factors to apply that same scale to both the position and scale of the items you're placing on the map.
Remember that scale factor you have to draw at = size it needs to be / size that it is
. So once you get the target sizes using the above methods you stick this in for the size it needs to be' and the
size that it isis (in my apps) a hardcoded
#define` statement. Or you could read everything in from an xml. Lots of ways to do that.