Skip to content

Dealing with iOS aspect ratios

November 29, 2012

So After last week’s frenzy of activity on Atomic Test pilot, I am now back on to finishing up Nuclien Rush….since I started it iOS 6 has come out, and more importantly the iPhone 5.

As you can guess that new super-wide screen of the new phone makes all my menu’s overlap and stuff. Here is a screenshot of the game running at iPhone 5 res – as you can see the text now overlaps, and the round numbers also overlap (5 and 0).

So what is the big deal, well a lot of the time people will handle different ratios by simply stretching the image to fit, but that looks terrible. As you can see things that are expected to be circular become ellipsoids, which would mean this would make your characters fat, or your trees dwarven…

So how do I deal with it? be prepared, what follows is pretty boring…

To start with I need to set my game up for an ideal ratio, when developing on PC I set my game to run in iPad 1 resolution (1024 / 768). I call this value my “reference screen resolution” and my entire game runs at this resolution regardless of what resolution the device actually is.

The input is obviously a problem, so if the player taps the screen in the middle of the device on an iPad that would return a value of 512 / 384. While on the retina iPad that gives me a value of 1024 / 768 clearly if my game uses these values it won’t work (because my game is running at the same resolution regardless of the actual screen it is being played on).

However it’s pretty easy to solve. I have a function that takes the raw inputs on the screen and assigns them to various arrays such as TapOnTouches[] ReleaseTaps[] Hold[] etc. (I try not to use the default gesture stuff, it never gives enough control). Every frame I just transform the input to my “reference screen resolution” like this (where ScreenResolution is the real resolution of the device):

TouchLocation = (TouchLocation / ScreenResolution) * ReferenceScreenRes;

So no I have my input lined up with my game and I can run all of the logic… Obviously when I draw things I need to move them to the right place and scale them accordingly…this is where it gets hard.

First up I need to translate the position, you can see how I do it in the function below.

The origin stuff is about the images anchor, by default images tend to draw from the top left, usually this isn’t desirable so people draw them from the centre (eg a box of 20X20 pixels would have an origin of 10X10 if I wanted to draw it from the middle). The meat of the function is pretty straight forward, it’s just the reverse of the above.

public static Vector2 Reposition(Vector2 Position, Vector2 Origin, Vector2 scale)

{
Vector2 ThisPosition = Vector2.Zero;

if (Origin != Vector2.Zero)
{
Position -= ((Origin * scale) * 0.5f);
}

ThisPosition = (Position / ReferenceScreenRes) * ScreenResolution;

if (Origin != Vector2.Zero)
{
ThisPosition += ((Origin * scale) * 0.5f);
}
return ThisPosition;
}

So now I have the right place to draw the thing. Next up I need the right scale….now this is where you have to consider what would be best for each objct in your game, when thinking about the different ratios you intend to support.

So if you want to stop something from stretching you would rescale it on one axis of the device. So in the case of translating from the iPad to the iPhone 4 the Ratio of the device changes in the vertical rather than the horizontal. So I pretty much scaled everything to the X value of the screen….this means then when things draw on the iPad they might have a bit more space between them vertically than on the iPhone.

public static float Rescale(float scale)
{
scale = (scale / ReferenceScreenRes.X) * ScreenResolution.X;
return scale;
}

What the hell am I talking about? well in this image you can see what the difference can be if you scale on the X of your screen Vs the Y when changing screen ratio. In this example the vertical height of the screen gets larger while the X horizontal stays the same. If the scale of the image is based on the Y resolution the image will get larger (and clip off the screen) while using X means it stays the same size.

So because the iPad is simply taller I always used scale on X to reduce the scale to iPhone, and just made sure I left enough space around things vertically. Really I should be using iPhone as my default resolution rather than iPad, but I like my games to look best on iPad, and this is the main reason things are now so damned hard!

Now with the iPhone 5 the screen has stretched out horizontally from the iPhone, meaning that scaling on X gives me bigger images, and everything overlaps.  So I need to use scale on Y sometimes so I added a new version of my function:

public static float Rescale(float scale, bool scaleonY)
{

if (!scaleonY)
{
scale = (scale / ReferenceScreenRes.X) * ScreenResolution.X;
}
else
{
scale = (scale / ReferenceScreenRes.Y) * ScreenResolution.Y;
}
return scale;
}

With my old games, I am simply hacking at the code to get things working at all three ratios, it’s ugly and horrible. With my next game, I will stop and rewrite something that considers the ratio and then scales accordingly…something along the lines of: (if refscreenres.X/ refscreenres .Y > RealSCreenRes.X / RealsScreenRes.Y – then pick the scale direction…). However that’s just a guess right now, I need to go and do some actual work to get it up and running, so expect an update at some point in the future.

My current method probably won’t work for you…

The above method doesn’t actually work for any games that involve playable spaces, it only works for UI, and simple games (that are pretty much just UI interfaces, like all of my games so far!)

Imagine you are making Tetris, and you have 3 squares and your ration is default ratio is 16:9 and you want to change it to 4:3….well the following would happen:

Worse yet, you collision code would be off because it wouldn’t be considering the size of things on the screen.

This means that if you are making an adventure game, and you don’t want fat characters you will have to actually draw more of the world on each side of the screen, or draw your game with borders (what the iPhone 5 does by default). So if you are feeling annoyed that your favourite game doesn’t support your fancy new phone, maybe now you know why! Many iPhone developers are now drawing extra bits on the sides of their gameplay spaces, or adding extra little frames to fill the screen…) Those extra 76 pixels that apple added really are a pain in the ass.

This is the reason I wrote the lyrics to the following song:

Advertisements

From → Uncategorized

Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: