understand scaling and ultimate config

Hello,

I am sorry I have to press on a very trite topic, but I read what I could about the config file and relative proper sizing of graphic elements, mostly I am referring to this thread:

http://coronalabs.com/blog/2013/09/10/modernizing-the-config-lua/

I tried to follow it in detail for as much as my newbie programming skills let me, but so far I still can’t have my background properly sized across devices.

With each configuration and sets of images I use I always have the background cut on top-bottom or sides (bleeding), or black stripes on edges of on the edges of wider/taller devices.

The ultimate question I have is: is there a way to get my background image to fit perfectly the screen edges on each device? If so what size should be the set of images I produce?

Sorry if I ask basic stuff, but I am new to this and keeping banging my head on this topic.

Thanks for your attention…

There are two ways to handle this.  Have your background be bigger than the devices your going to run it on.  For instance, if you’re base screen is 320x480, the 16:9 shaped devices (mostly phones) need a 320x570 background (give or take a few pixels.  Each device is different).  The iPads being the most square shape (4:3 ratio) need a 360x480 background.   Some Android tablets are 1.6:1.  Older iPhones (3/4 family) are 1.5:1 (3:2) which is the basis of the 320x480 shape).  Your background therefore should be based on a 360x570 to cover the largest ranges of devices, knowing that on all devices, some of it’s going to get cut off.

Not all apps can be designed to work this way.  If you need your background to fit better, then you have to have multiple backgrounds, like a 16:9, a 4:3 a 1.6:1 etc. for the different devices you want to support, then you have to do device detection (or determine the pixel Width and height, calculate the ratio of the screen and then load the background that fits the best.

Thanks a lot Rob,

You gave me a much clearer understanding of where to look at.

Now, assuming my app targets phones only, let’s say iphones from 4 to 6, I should create a pair of 320x480 (3:2) and 320x570 (16:9)

images to cover perfectly the screen of said devices, right?

And then the ‘definitive config.lua’ file would handle the picking of the proper image or should I implement proper code to do it into my project? If so do you have examples for that?

Thank You!!!

The config.lua has nothing to do with picking a background to use. 

As far as code, the ultimate config.lua tutorial has code at the top that calculates the aspect ratio of the device.  Once you know the aspect ratio, then you can do a simple test:

local aspectRatio = display.contentWidth / display.contentHeight – (for a portrait app)

local aspectRatio = display.contentHeight / display.contentWidth – (for a landscape app)

if aspectRatio > 1.5 then

     – use your wide screen background

else

     – use your iPhone 4 background

end

or something like that…

Rob

Hi Rob,

I applied what you suggested with this code:

 local aspectRatio = display.contentWidth / display.contentHeight &nbsp;&nbsp; if aspectRatio \< 1.5 then &nbsp;&nbsp;&nbsp; textNumber.y = textNumber.y + 20 &nbsp;&nbsp;&nbsp; minusButton.y = minusButton.y - 15 &nbsp;&nbsp;&nbsp; resetButton.y = resetButton.y - 15 &nbsp; end

Instead of displaying another image as a consequence of smaller (iphone) display I decided to replace the objects in order for them to be in a relative position with the background image.

While testing on simulator this code affects the behaviour both in iphone 4 AND iphone 5.

Shouldn’t be the if statement be triggered only when simulating on devices as iphone 3-4???

You need to print out the value of aspectRatio.  If your app is landscape, You may need to flip the width and height values.

Rob

Thanks Rob,

Actually the problem was I didn’t put =< the ‘equal’ condition in the if statement. That made it work for iphone 3-4 screens which aspect ratio is exactly 1.5.

Now I have the object placement across devices as I want it :). I

I notice a strange behaviour though… The backgorund image I have fit perfectly an Iphone 4 screen but it gets ‘trimmed’ (black bars) laterally on Iphone (3). Shouldn’t it be render similarly on those devices since they have the same aspect ratio? I’m using the ultimate config template, but i doesn’t discern iphone 3 from iphone 4, does it?

Fixed by passing greater width value in display.newImageRect.

Thanks Rob for previous hints!

Or you can dynamically scale the background image; it won’t be “pixel perfect”, which is really the point of the new ultimate config, but for a background image, i think it’s perfectly acceptable.  This will zoom into the image, making it always fit, no black bars.

I left my background images at 570x380 (landscape), then did this:

 local function scaleBackground(originalWidth, originalHeight) local widthFactor = (display.contentWidth / originalWidth) local heightFactor = (display.contentHeight / originalHeight) local scaleFactor -- pick greater of either height or width so that it will zoom in appropriately -- with no black bars on any side if (heightFactor \> widthFactor) then scaleFactor = heightFactor else scaleFactor = widthFactor end local newWidth = math.ceil(scaleFactor \* originalWidth) local newHeight = math.ceil(scaleFactor \* originalHeight) return newWidth, newHeight end newWidth, newHeight = scaleBackground(570, 380) background = display.newImageRect( filename, newWidth, newHeight)

If my calculations aren’t right, or there’s an easier way to determine this, I hope someone will correct me.

Thanks,

Dave

Hello Dave,

Thanks for your contribution!

Your method of zooming into the image to fit it into the screen is what I always wanted to achieve when approaching to content scaling/placing.

So thank you for that. I am very new to programming so I can’t evalue properly the effectiveness of your code but it looks well written to me. The background for my current project must be precisely allined with the objects it contains, so for now I’ll go with my solution since it works good, but I’ll surely keep your snippet to implement into my next project…

Thanks again!

Hi

I am also new to corona sdk and one of my major issues so far is this scaling thing. Is there no tutorial video preferably that just nails this issue out as it appears more questions been asked despite all the explanations. I am stuck with this also in my game and I have a deadline to get it to app stores, for my testing of the game, I end up just using background colors.

Please any help will be appreciated if one can provide a simple video tutorial to show how to scale or best method for portrait games on the different mobile sizes maybe separate for android and iOS.

There are a few tutorials that cover this topic including content scaling, the ultimate config.lua (which really should be replaced by) and the Modernizing the ultimate config.lua tutorials

https://www.youtube.com/watch?v=RwVlzJtQWd8

https://www.youtube.com/watch?v=QCU_G3GCerg

http://coronalabs.com/blog/2010/11/20/content-scaling-made-easy/

http://coronalabs.com/blog/2012/12/04/the-ultimate-config-lua-file/

http://coronalabs.com/blog/2013/09/10/modernizing-the-config-lua/

This should help you understand all of this.  But basically to sum things up you can either have:

a) a fixed content area (i.e. 320 x 480) knowing that 0, 0 will not likely be the top, left of the screen and display.contentWidth, display.contentHeight will likely not be the bottom, right.  Corona SDK has API’s to get the difference between 0, 0 and the top, left.  But basically on a wide device like an iPad, the left edge will be a negative value like -20.  On a tall device like an iPhone 5, the top will be at -44.  

b) use a content area that changes on a device by device basis that makes sure 0, 0 is top, left and that display.contentWidth,display.contentHeight are bottom, right.  In this case you position things relative to the center or the edge and things can move depending on the devices shape.

In both cases, your background should be big enough that it covers all devices.  If your core content area is based on 320x480, the recommended background is 360x570.  This covers most all devices.  Understanding that depending on the device some of the background will be off screen and the background must be designed around this.

Rob

There are two ways to handle this.  Have your background be bigger than the devices your going to run it on.  For instance, if you’re base screen is 320x480, the 16:9 shaped devices (mostly phones) need a 320x570 background (give or take a few pixels.  Each device is different).  The iPads being the most square shape (4:3 ratio) need a 360x480 background.   Some Android tablets are 1.6:1.  Older iPhones (3/4 family) are 1.5:1 (3:2) which is the basis of the 320x480 shape).  Your background therefore should be based on a 360x570 to cover the largest ranges of devices, knowing that on all devices, some of it’s going to get cut off.

Not all apps can be designed to work this way.  If you need your background to fit better, then you have to have multiple backgrounds, like a 16:9, a 4:3 a 1.6:1 etc. for the different devices you want to support, then you have to do device detection (or determine the pixel Width and height, calculate the ratio of the screen and then load the background that fits the best.

Thanks a lot Rob,

You gave me a much clearer understanding of where to look at.

Now, assuming my app targets phones only, let’s say iphones from 4 to 6, I should create a pair of 320x480 (3:2) and 320x570 (16:9)

images to cover perfectly the screen of said devices, right?

And then the ‘definitive config.lua’ file would handle the picking of the proper image or should I implement proper code to do it into my project? If so do you have examples for that?

Thank You!!!

The config.lua has nothing to do with picking a background to use. 

As far as code, the ultimate config.lua tutorial has code at the top that calculates the aspect ratio of the device.  Once you know the aspect ratio, then you can do a simple test:

local aspectRatio = display.contentWidth / display.contentHeight – (for a portrait app)

local aspectRatio = display.contentHeight / display.contentWidth – (for a landscape app)

if aspectRatio > 1.5 then

     – use your wide screen background

else

     – use your iPhone 4 background

end

or something like that…

Rob

Hi Rob,

I applied what you suggested with this code:

 local aspectRatio = display.contentWidth / display.contentHeight &nbsp;&nbsp; if aspectRatio \< 1.5 then &nbsp;&nbsp;&nbsp; textNumber.y = textNumber.y + 20 &nbsp;&nbsp;&nbsp; minusButton.y = minusButton.y - 15 &nbsp;&nbsp;&nbsp; resetButton.y = resetButton.y - 15 &nbsp; end

Instead of displaying another image as a consequence of smaller (iphone) display I decided to replace the objects in order for them to be in a relative position with the background image.

While testing on simulator this code affects the behaviour both in iphone 4 AND iphone 5.

Shouldn’t be the if statement be triggered only when simulating on devices as iphone 3-4???

You need to print out the value of aspectRatio.  If your app is landscape, You may need to flip the width and height values.

Rob

Thanks Rob,

Actually the problem was I didn’t put =< the ‘equal’ condition in the if statement. That made it work for iphone 3-4 screens which aspect ratio is exactly 1.5.

Now I have the object placement across devices as I want it :). I

I notice a strange behaviour though… The backgorund image I have fit perfectly an Iphone 4 screen but it gets ‘trimmed’ (black bars) laterally on Iphone (3). Shouldn’t it be render similarly on those devices since they have the same aspect ratio? I’m using the ultimate config template, but i doesn’t discern iphone 3 from iphone 4, does it?

Fixed by passing greater width value in display.newImageRect.

Thanks Rob for previous hints!

Or you can dynamically scale the background image; it won’t be “pixel perfect”, which is really the point of the new ultimate config, but for a background image, i think it’s perfectly acceptable.  This will zoom into the image, making it always fit, no black bars.

I left my background images at 570x380 (landscape), then did this:

 local function scaleBackground(originalWidth, originalHeight) local widthFactor = (display.contentWidth / originalWidth) local heightFactor = (display.contentHeight / originalHeight) local scaleFactor -- pick greater of either height or width so that it will zoom in appropriately -- with no black bars on any side if (heightFactor \> widthFactor) then scaleFactor = heightFactor else scaleFactor = widthFactor end local newWidth = math.ceil(scaleFactor \* originalWidth) local newHeight = math.ceil(scaleFactor \* originalHeight) return newWidth, newHeight end newWidth, newHeight = scaleBackground(570, 380) background = display.newImageRect( filename, newWidth, newHeight)

If my calculations aren’t right, or there’s an easier way to determine this, I hope someone will correct me.

Thanks,

Dave