Content-Viewable-Screen size-Width-Height-anchorX-anchorY-contentWidth-contentHeight-dynamic display confusion! :)

To anyone whom I hope is concerned,

I have been reading (to put it lightly) from EVERY available book on the subject of Corona SDK and Lua over the past year. I have every book title available from Amazon on my Kindle, excluding the plethora of mini-eBooks that seem to go on forever at a ridiculous and desperate rate.

As well, I have read various online resources.

I must say, I am dumbfounded, (to put that lightly too) with the whole displaying of an app or game on multiple devices with varying screen resolutions. I am new to Mobile app development, but not to FLASH or DIRECTOR’S LINGO language back in the MACRO MEDIA days. I am anxious for the GUI COMPOSER to bridge the gap between the artist and the programmer for Corona Users. I feel very confident with ALL I have read, and I do apologize for any ignorance on the subject; but I am no idiot, so I do not understand why I am having such a difficult time with this.

At this point, NONE of the books that I have purchased, have “HIT IT HOME” for me.  I do tend to look too deeply into things, so I know I understand more than I can let on at this point.

I see two games in my head that causes the confusion for me.

  1. A pool table game, whose “POOL TABLE” graphic must remain rectangular, CONSTRAINED, and should not be “zoomed-even” in the config settings for that game, as some of the pool table pockets could be OFF screen on some devices. Right? And the zoomStretch will make our table look stupid.

I understand, I guess, that letterbox will work, but, how does a person code to use the black space on different devices?

If I program for a 320 X 480 screen, how can I access pixel 481 on a device with more pixels?

If I program for a higher res screen, say, 800 X 1200, I now have access to pixel 481, but how will this game work on the 320 X 480?

I assume the CORONA UNITS are making the magic?

A target device. Does that device get the best view?; and everything else is just, “eh”, it’s playable.

  1. Then I see a game that has no edges, an asteroid game for example. 

Confusion sets in when I try and understand how one programs an object to move within the confines of a pool table in one game, and the open space of a “boundless” game, all the while making these look “SIMILAR” on multiple devices.

If I program an object to be 100 pixels from the top on a small-res device, and play that same game on a high res device, the battle field has changed, and 100 pixels is no longer a suitable location, the enemies are still relative I am assuming. The confusion is compounded in my head, when I think of the two different game scenarios above.

I know I am missing a very small point.

If anyone would like to help a person in need, I am beating myself up over here. I am beginning to believe that all the books I have purchased barely scratch the surface of creating a game for Multiple devices, claiming it is SO EASY TO MAKE A GAME. I understand there are different calibers of games and apps, and some will be out of a single developers league, but a book needs to be written that shows what really goes behind a TYPICAL game, not a prototype, from start to finish, using CORONA SDK.

Hello World programs need to stop! :wink:

Please help, I have read myself dumb!

:slight_smile:

I’m not giving up.

Chris

Ok, I’ve been where you are, so trust me when I say… Sit back, clear your mind and take a breath.

It can start out being a simple subject and quickly get real confusing. But if you give me a chance I’ll try to explain it as clearly as possible.

Let’s begin…

First, think about what a screen is. It is simply a rectangle of pixels. Apple and Google refer to those pixels in different ways. Also, all screens are different - different sizes, different shapes, different resolutions.

So, the first thing we do is take a particular example and consider it in the definition of one screen. Let’s take the pool table example and consider it in the terms of the iPad 2.

The pool table itself can’t be a different shape or size - it is a specific rectangle and the iPad can’t be a different shape or size. It too is a specific rectangle. In our terms we are looking at an iPad 2 of 768x1024 and (for giggles) a pool table of exactly 768x1024.

You create an image of that size. In your Corona Lua code you load that image using this line of code:

local img = display.newImageRect( "pooltable.png", 768, 1024 ) img.x, img.y = display.contentCenterX, display.contentCenterY

This code also places that image in the centre of the screen. We’ll come back to that later. (Yes, I’m English.)

Now, the first thing you’ll notice (other than my correct spelling of the word ‘centre’ ;) ) is that if we were to run the code on a different device which does not have the same resolution/dimensions as our iPad 2, it would look wrong. For example, if we run this code on an iPhone 5s the image would be centred but it would not be tall enough. (Let’s ignore the config.lua file for now, though it is important.)

The image would not be tall enough because the iPhone 5s has a proportionately taller screen. There is no way to get round this.

So what do we do? We need to render something in that space. So we just have a bigger image than we would need for screens which differ from our target screen resolution.

How do we know what to target or what those ‘other’ screens might do? Won’t there be big black bars? Won’t it get distorted?

In order: We don’t. Only if we don’t have an image big enough. No.

Those other screens could be completely ridiculous sizes/dimensions, but we can bet they won’t be because there are only so many sizes people want to use in the real world. We won’t have big black bars because we can either have a really big background image or repeat our image or just fill with a single colour. It won’t get distorted because our config.lua will be set to letterbox. This means nothing gets cropped off our game (which would be usually very, very bad) and nothing gets distorted (similarly bad.) (This is also what the config.lua is for, so forget that for now.)

So, for screens which do not match our 768x1024 we are going to have to accept that there is screen area that we will need to fill in with pretty pictures/blank colour, etc.

Fortunately, because Corona is awesome, our pool table image will scale properly to fit onto all screens whether they are 768x1024 or half, or double, or triple that resolution. That is because the config.lua is configured to say “I am coding for this screen resolution, please rescale my content to fit properly no matter what device you run on. Oh, btw, don’t stretch or crop.”

So, we now have a nice image of a pool table which renders properly on all screens, though it might leave a bit of space around the top and bottom OR the left and right…

Let’s not worry about the blank spaces just yet.

Let’s worry about the size of our pool table image.

For starters, Corona will resize our image to our physical device’s screen. It actually re-samples it (on Apple devices, at least - I don’t know about Android) and displays it as we intend it to be…

Our 768x1024 image which be resized to fit on screen. Period.

If we are running on a device with a 1536x2048 screen the image will be scaled up to fit. Likewise, on a 384x512 screen the image will be scaled down. Awesome. Let’s leave that there.

If we want the pool table image to take advantage of all those different screen resolutions (read: qualities - because, let’s face it, the iPhone 5s has a better screen than the iPhone 3GS, etc) we will want to create multiple versions of our pool table. The way we do this is by following the instructions in a number of blog posts on the Corona site and simply open PhotoShop, scale our image down (always start with the biggest image possible) and save it as “pooltable-x2.png”, “pooltable-x15.png” etc. We always save the target screen resolution as “pooltable.png” - the default.

What’s this about? Well, if you read the blog posts and Guides on Corona’s site, you’ll see that each file extension targets a different scaling of our target screen. So, if our target screen size is 768x1024 we want to define a config.lua entry for 1536x2048 with an extension of “-x2”. Ok, it’s not really an extension, but it is a modification of the filename which tells Corona which screen the image file is for.

There is one problem here. Sometimes a screen does not have a direct scaling. For example, the number of pixels on an Android screen might be an exact multiplication of our target screen * 2.2 but not in the same dimensions. Maybe we’ve defined one for * 2 and * 2.5. This could mean that our Android screen will pick up the wrong image size.

The answer? Try not to worry about it. Most screens will scale properly and Corona is clever enough to pick the most appropriate image and scale it up or down as necessary.

So, now, we’ve got our pool table image rendering in the centre of our screen and it looks great. The only issue is that it’s got big black bars either top and bottom or left and right, depending on whether our real world device is taller or wider than our imaginary target device screen resolution.

Fill it in!..

So, when you are playing with different screen resolutions and sizes of devices (that rhymes!) you’ll notice that, for example, taller devices may tend to shove everything toward the top. The solution to this is two-fold.

Firstly, you need to provide a loading image which tells iOS (I’m not sure about Android, but again, read the blog posts and Guide) to switch to “tall mode.” This is as simple as providing a default.png for each major screen resolution that you want to support in the iOS world. In Android world I would guess it’s more flexible and the device will be very forgiving. Tall Mode in iOS is simply saying “I know you are taller than a regular iOS device and I want to make use of that.”

You will also want to target the centre of the screen properly. This is where it can get really tricky. But don’t worry. Keep your head clear and maybe go get a cup of tea first…

First off, setup your config.lua to place your app’s screen at the top left of the device. (Ok, I’ll admit now that this is simply my preference and many people may do it differently.)

You do this by putting this in your config.lua:

xAlign = "left", yAlign = "top",

Now, in your code you will need to understand where the real world centre of your device’s screen is. You can do this by making use of the lesser-known ‘actualCenter’:

display.actualCenterX, display.actualCenterY = display.actualContentWidth\*.5, display.actualContentHeight\*.5

You might be tempted to use the ‘pixel’ values in the display.* library but don’t. There be dragons.

You will now load and position your pool table image in the centre of the screen like this:

local img = display.newImageRect( "pooltable.png", 768, 1024 ) img.x, img.y = display.actualCenterX, display.actualCenterY

So, now we have told iOS (and Android) to use the full screen, avoid those annoying black bars imposed by the OS and by Corona, calculated where the real centre of the screen is (so all our screen positions are positive values and positioned an image of the correct size and resolution for the device in the middle of the physical device’s screen.

I hope that helps. It is the boiling down of a lot of trial and error. If you need clarification on anything please ask.

I figured it would be useful to have a list of the Corona blog posts which are relevant to this thread…

Resolution Independence: Adaptive Content Scaling in Corona
Approximating Density Independence on Android
The Point of Resolution Independence: iOS and iPhone 6 Plus
Tutorial: Modernizing the config.lua
Tutorial: the Ultimate “config.lua” File
Developing for iPad Retina Display
Content Scaling Made Easy

And for good luck, here’s the relevant Guides…

http://docs.coronalabs.com/daily/guide/basics/configSettings/index.html#content-scaling

http://docs.coronalabs.com/daily/guide/basics/configSettings/index.html#dynamic-image-selection

you pick a “native” content size for your app, Corona scales things to fit native device resolution.  it’s simple, really, once you “get it” (just give it time, it’ll sink in eventually)  then you just work in your native content size coordinates.

re zoomEvent/zoomStretch/letterbox:  if you have a relatively modern HDTV you’ ve probably seen a “zoom” control on it with a couple different modes for “fitting” SD content onto it - very similar to what Corona does.

compare the relative aspect ratios (wide/tall) of your native content versus the device, then fit your content to the device by…

zoomStretch:  will scale each axis independently to fit, will distort if not same aspects

  all of your native content size remains visible, exactly, and no more

letterbox:  will scale longest axis to fit, scale shorter axis by same ratio - allowing it to pillarbox/letterbox

  all of your native content size remains visible, and gain extra ‘blank’ space of letterboxes

zoomEven:  will scale shortest axis to fit, scale longer axis by same ratio - allowing it to bleed over

  some of your native content size is not visible, lost to bleed, but no ‘blank’ letterboxes

then use display.viewableContentWidth/Height and/or display.actualContentWidth/Height to access/determine letterbox/bleed

  :o  what a post… just when i needed it

Thank you very much, especially mister horacebury, and thank you davebollinger for the summary :slight_smile:

Someone should definitely pin this post  :slight_smile:

Thank you again…

Ok, I’ve been where you are, so trust me when I say… Sit back, clear your mind and take a breath.

It can start out being a simple subject and quickly get real confusing. But if you give me a chance I’ll try to explain it as clearly as possible.

Let’s begin…

First, think about what a screen is. It is simply a rectangle of pixels. Apple and Google refer to those pixels in different ways. Also, all screens are different - different sizes, different shapes, different resolutions.

So, the first thing we do is take a particular example and consider it in the definition of one screen. Let’s take the pool table example and consider it in the terms of the iPad 2.

The pool table itself can’t be a different shape or size - it is a specific rectangle and the iPad can’t be a different shape or size. It too is a specific rectangle. In our terms we are looking at an iPad 2 of 768x1024 and (for giggles) a pool table of exactly 768x1024.

You create an image of that size. In your Corona Lua code you load that image using this line of code:

local img = display.newImageRect( "pooltable.png", 768, 1024 ) img.x, img.y = display.contentCenterX, display.contentCenterY

This code also places that image in the centre of the screen. We’ll come back to that later. (Yes, I’m English.)

Now, the first thing you’ll notice (other than my correct spelling of the word ‘centre’ ;) ) is that if we were to run the code on a different device which does not have the same resolution/dimensions as our iPad 2, it would look wrong. For example, if we run this code on an iPhone 5s the image would be centred but it would not be tall enough. (Let’s ignore the config.lua file for now, though it is important.)

The image would not be tall enough because the iPhone 5s has a proportionately taller screen. There is no way to get round this.

So what do we do? We need to render something in that space. So we just have a bigger image than we would need for screens which differ from our target screen resolution.

How do we know what to target or what those ‘other’ screens might do? Won’t there be big black bars? Won’t it get distorted?

In order: We don’t. Only if we don’t have an image big enough. No.

Those other screens could be completely ridiculous sizes/dimensions, but we can bet they won’t be because there are only so many sizes people want to use in the real world. We won’t have big black bars because we can either have a really big background image or repeat our image or just fill with a single colour. It won’t get distorted because our config.lua will be set to letterbox. This means nothing gets cropped off our game (which would be usually very, very bad) and nothing gets distorted (similarly bad.) (This is also what the config.lua is for, so forget that for now.)

So, for screens which do not match our 768x1024 we are going to have to accept that there is screen area that we will need to fill in with pretty pictures/blank colour, etc.

Fortunately, because Corona is awesome, our pool table image will scale properly to fit onto all screens whether they are 768x1024 or half, or double, or triple that resolution. That is because the config.lua is configured to say “I am coding for this screen resolution, please rescale my content to fit properly no matter what device you run on. Oh, btw, don’t stretch or crop.”

So, we now have a nice image of a pool table which renders properly on all screens, though it might leave a bit of space around the top and bottom OR the left and right…

Let’s not worry about the blank spaces just yet.

Let’s worry about the size of our pool table image.

For starters, Corona will resize our image to our physical device’s screen. It actually re-samples it (on Apple devices, at least - I don’t know about Android) and displays it as we intend it to be…

Our 768x1024 image which be resized to fit on screen. Period.

If we are running on a device with a 1536x2048 screen the image will be scaled up to fit. Likewise, on a 384x512 screen the image will be scaled down. Awesome. Let’s leave that there.

If we want the pool table image to take advantage of all those different screen resolutions (read: qualities - because, let’s face it, the iPhone 5s has a better screen than the iPhone 3GS, etc) we will want to create multiple versions of our pool table. The way we do this is by following the instructions in a number of blog posts on the Corona site and simply open PhotoShop, scale our image down (always start with the biggest image possible) and save it as “pooltable-x2.png”, “pooltable-x15.png” etc. We always save the target screen resolution as “pooltable.png” - the default.

What’s this about? Well, if you read the blog posts and Guides on Corona’s site, you’ll see that each file extension targets a different scaling of our target screen. So, if our target screen size is 768x1024 we want to define a config.lua entry for 1536x2048 with an extension of “-x2”. Ok, it’s not really an extension, but it is a modification of the filename which tells Corona which screen the image file is for.

There is one problem here. Sometimes a screen does not have a direct scaling. For example, the number of pixels on an Android screen might be an exact multiplication of our target screen * 2.2 but not in the same dimensions. Maybe we’ve defined one for * 2 and * 2.5. This could mean that our Android screen will pick up the wrong image size.

The answer? Try not to worry about it. Most screens will scale properly and Corona is clever enough to pick the most appropriate image and scale it up or down as necessary.

So, now, we’ve got our pool table image rendering in the centre of our screen and it looks great. The only issue is that it’s got big black bars either top and bottom or left and right, depending on whether our real world device is taller or wider than our imaginary target device screen resolution.

Fill it in!..

So, when you are playing with different screen resolutions and sizes of devices (that rhymes!) you’ll notice that, for example, taller devices may tend to shove everything toward the top. The solution to this is two-fold.

Firstly, you need to provide a loading image which tells iOS (I’m not sure about Android, but again, read the blog posts and Guide) to switch to “tall mode.” This is as simple as providing a default.png for each major screen resolution that you want to support in the iOS world. In Android world I would guess it’s more flexible and the device will be very forgiving. Tall Mode in iOS is simply saying “I know you are taller than a regular iOS device and I want to make use of that.”

You will also want to target the centre of the screen properly. This is where it can get really tricky. But don’t worry. Keep your head clear and maybe go get a cup of tea first…

First off, setup your config.lua to place your app’s screen at the top left of the device. (Ok, I’ll admit now that this is simply my preference and many people may do it differently.)

You do this by putting this in your config.lua:

xAlign = "left", yAlign = "top",

Now, in your code you will need to understand where the real world centre of your device’s screen is. You can do this by making use of the lesser-known ‘actualCenter’:

display.actualCenterX, display.actualCenterY = display.actualContentWidth\*.5, display.actualContentHeight\*.5

You might be tempted to use the ‘pixel’ values in the display.* library but don’t. There be dragons.

You will now load and position your pool table image in the centre of the screen like this:

local img = display.newImageRect( "pooltable.png", 768, 1024 ) img.x, img.y = display.actualCenterX, display.actualCenterY

So, now we have told iOS (and Android) to use the full screen, avoid those annoying black bars imposed by the OS and by Corona, calculated where the real centre of the screen is (so all our screen positions are positive values and positioned an image of the correct size and resolution for the device in the middle of the physical device’s screen.

I hope that helps. It is the boiling down of a lot of trial and error. If you need clarification on anything please ask.

I figured it would be useful to have a list of the Corona blog posts which are relevant to this thread…

Resolution Independence: Adaptive Content Scaling in Corona
Approximating Density Independence on Android
The Point of Resolution Independence: iOS and iPhone 6 Plus
Tutorial: Modernizing the config.lua
Tutorial: the Ultimate “config.lua” File
Developing for iPad Retina Display
Content Scaling Made Easy

And for good luck, here’s the relevant Guides…

http://docs.coronalabs.com/daily/guide/basics/configSettings/index.html#content-scaling

http://docs.coronalabs.com/daily/guide/basics/configSettings/index.html#dynamic-image-selection

you pick a “native” content size for your app, Corona scales things to fit native device resolution.  it’s simple, really, once you “get it” (just give it time, it’ll sink in eventually)  then you just work in your native content size coordinates.

re zoomEvent/zoomStretch/letterbox:  if you have a relatively modern HDTV you’ ve probably seen a “zoom” control on it with a couple different modes for “fitting” SD content onto it - very similar to what Corona does.

compare the relative aspect ratios (wide/tall) of your native content versus the device, then fit your content to the device by…

zoomStretch:  will scale each axis independently to fit, will distort if not same aspects

  all of your native content size remains visible, exactly, and no more

letterbox:  will scale longest axis to fit, scale shorter axis by same ratio - allowing it to pillarbox/letterbox

  all of your native content size remains visible, and gain extra ‘blank’ space of letterboxes

zoomEven:  will scale shortest axis to fit, scale longer axis by same ratio - allowing it to bleed over

  some of your native content size is not visible, lost to bleed, but no ‘blank’ letterboxes

then use display.viewableContentWidth/Height and/or display.actualContentWidth/Height to access/determine letterbox/bleed

  :o  what a post… just when i needed it

Thank you very much, especially mister horacebury, and thank you davebollinger for the summary :slight_smile:

Someone should definitely pin this post  :slight_smile:

Thank you again…