Scroll view problems

Hi everyone, 

I’m developing my first game and I’ve an issue with the ScrollView. 

In both emulator and phone, it works fine. When a friend of mine try my app on his own phone the main menu file (which contains a full screen scrollView) seems to be “too large” for the whole screen.

Here’s my code:

W=display.viewableContentWidth

H=display.viewableContentHeight

mainMenu = widget.newScrollView

{

left = 0,

top = 0,

width =W,

height = H,

scrollWidth=0,

verticalScrollDisabled =true,

backgroundColor={0,0,0},

listener=scrollListener

}

mainMenu.x=W/2

mainMenu.y=H/2

Can anyone helps? Thanks a lot =)

What’s your config.lua?

Here it is:

application =

{

content =

{

width = 320,

height = 480, 

scale = “letterbox”,

fps = 60,

–[[

imageSuffix =

{

   ["@2x"] = 2,

},

–]]

},

–[[

– Push notifications

notification =

{

iphone =

{

types =

{

“badge”, “sound”, “alert”, “newsstand”

}

}

},

–]]    

}

Try:

W=display.actualContentWidth

H=display.actualContentHeight

Check out the reply I made on this topic. 

https://forums.coronalabs.com/topic/62844-scrollview-inconsistent-between-ios-and-android/#entry327435

Thank you both for your answers. I’ve just tryied both solutions and both works fine. Settings W and H with actualContentWidth and actualContentHeight makes everything go a bit down. Why?
Using InfySnip’s solution makes the whole objects dimensions and coordinates go crazy. Why?
Just another question: should I use this solutions both or just one of them? :slight_smile:

I don’t want to get into a huge discussion on content areas. We’ve written about this many times before, but basically your current config.lua is defining a content area that is exactly 320 points wide and 480 points high. This is a perfect fit for an iPhone 4 and some other older Android devices (Corona handles scaling it to 640x960 for instance on the iPhone 4). But every other device is going to have some extra space outside of this. If you’re background is designed to fit 320x480, then you will get black “letterbox” bars on two sides of the screen. For an iPhone 5, there will be 44 points of black at the top (I’m going to use portrait orientation for this discussion) and 44 points of black at the bottom since the actual screen when scaled to 320 points wide, is 568 points high (568-480 = 88 points of black space evenly divided along the screen).

In this configuration 0, 0 to Corona will be the left edge, but will be 44 points below the top. In other words, the top left corner is 0, -44. The bottom right corner will be 320, 568.

In this setup the various display functions that gets sizes will be:

display.contentWidth = 320

display.actualContentWidth = 320

display.contentHeight = 480 – what you have in your config.lua

display.actualContentHeight = 568 – the computed size.

On an iPad, its a bit different. You will find that due to it’s more square shape, the actual content width is 360, not 320 and you will have two letterbox bars on the sides that are 20 points each. The height will be an exact fit at 480 points. Thus the display values will be:

display.contentWidth = 320  – the size in your config lua

display.actualContentWidth = 360 – the computed size

display.contentHeight = 480

display.actualContentHeight = 480

Now top, left is -20, 0 and bottom right is 360, 480.

In either case, to hide the letterbox bars simply make your background big enough to fill the space and don’t put anything important in the “bleed” areas (i.e. those areas that will be off screen on some devices). Backgrounds should be 360x570 (other devices are a bit taller than the iPhone 5) and centered. On the iPad  some of the top and bottom will be hidden, on the phone some on the sides will be off screen.

Then you have to take into account, when positioning things, that the screen is bigger than the content area. You can use the two API calls:

display.screenOriginX – https://docs.coronalabs.com/daily/api/library/display/screenOriginX.html

display.screenOriginY – https://docs.coronalabs.com/daily/api/library/display/screenOriginY.html

to get the offset values of the top left from 0, 0 and use display.actualContentWidth and display.actualContentHeight to get to the bottom right corner as needed.

For many people, they want 0, 0 to be the top, left and display.contentWidth, display.contentHeight to be the bottom, right. This is where @InfiSnyp’s suggestion comes into play. We have a blog post called Modernizing Config.lua or some thing similar that covers this technique. It creates a content area that exactly fits the device you are on, but it will be slightly different on all screens. The beneift is that your right edge is always a .x of 0, your top edge is always a .y of 0 and so on. You can use display.contentCenterX and display.contentCenterY to center things or place them some offset from the center. For things that need to be near the edge you can position things relative to the edge.

An easy way to think about this is lets say you’re building a game and you want to show the score on the top right. You can position it at .x = 20 and .y = display.contentWidth - 60. Because a phone is narrower, the score will be closer to center than it will be on an iPad. On an iPad with the extra pixels on each side, that score will move towards the right edge on the bigger screen. 

If your background has a container where the score supposed to be, this will be a problem since the score moves based on the actual screen size. But you can solve this by having the score background be a separate asset and not part of the actual background and move that element with the score.

Both ways work. You have to think differently about how to get the screen size and were top,left and bottom,right end up.

In your example here:
 

W = display.actualContentWidth H = display.actualContentHeight mainMenu = widget.newScrollView { left = 0, top = 0, width = W, height = H, scrollWidth = 0, verticalScrollDisabled = true, backgroundColor = { 0, 0, 0}, listener = scrollListener } mainMenu.x = W / 2 mainMenu.y = H / 2

You don’t need to set top and left in the constructor since you immediately re-position the scrollView. If you wanted to just use top and left, and not re-position it, you could do instead:

W = display.actualContentWidth H = display.actualContentHeight mainMenu = widget.newScrollView { left = 0 + display.screenOriginX, top = 0 + display.screenOriginY, width = W, height = H, scrollWidth = 0, verticalScrollDisabled = true, backgroundColor = { 0, 0, 0}, listener = scrollListener }

Rob

Thanks again for your answer Rob,I’m rally glad for your help. I’ve just read the modernizing config.lua article and some doubts about content areas are gone. I just want to ask: should I set my config.lua as infiSnyp suggest or should I use the 800x1200 layout to be sure my app will work in every android and ios device? Should I use a different config.lua for building apps for tablet and smartphone or can I use the same for both?
Thanks again :slight_smile:

Apple and Google really seem to want to keep things in 320 point based systems.  Some people like the larger content area. I tend to stay with 320x480 myself, though I do use the Modernizing config.lua idea, just with the smaller define area for games. I understand that my things on the screen will likely move around and not be the same, fixed distance away from each other.  Others want to make sure object B is 100 px a way from object A and that’s a bit harder to do with the Modernizing one.

Back to the size thing, if you’re going to be using the widget.* API’s you should certainly stay at 320x480 for now. They don’t scale for larger content areas.

If you’re building a business type app you might want to consider “adaptive” scaling. There are some blog posts on that as well. The gist here is that objects on the phone and on the tablet are going to be close to the same size. The config.lua above, your buttons and such on an iPad will visibly be 2-3 times larger than it appears on the phone.  Adaptive will give you a 320x480 size on a phone and give you a 1024x768 size on a tablet allowing you to fit more stuff instead of just a zoomed up phone app. Of course this takes more work to make it look right :slight_smile:

Rob

I’d like to set all of the objects in my game be x pixels away from each other. How can I do this? And which effect could I create if I let my objects “move around”?

Either method will let you position things fixed distances for objects. You might be better off just keeping your existing config.lua and just not have anything important in the bleed areas.

Rob

I’m using the aspectratio config.lua. I’ve just placed all of my objects and tried on smartphone emulator. It works nice.
I’ve executed the same code using an Ipad air emulator and I’ve noticed that all of the objects keep their coordinates while the dimensions change. Is there a way to keep proportions even if device changes? I mean…if I have a square object it should keep his dimensions and still be a square even in a rectangular screen, isn’t it?

Can you post your config.lua?

I’ve just modified my config.lua, and now everything works fine.

Thanks a lot for your support guys =)

What’s your config.lua?

Here it is:

application =

{

content =

{

width = 320,

height = 480, 

scale = “letterbox”,

fps = 60,

–[[

imageSuffix =

{

   ["@2x"] = 2,

},

–]]

},

–[[

– Push notifications

notification =

{

iphone =

{

types =

{

“badge”, “sound”, “alert”, “newsstand”

}

}

},

–]]    

}

Try:

W=display.actualContentWidth

H=display.actualContentHeight

Check out the reply I made on this topic. 

https://forums.coronalabs.com/topic/62844-scrollview-inconsistent-between-ios-and-android/#entry327435

Thank you both for your answers. I’ve just tryied both solutions and both works fine. Settings W and H with actualContentWidth and actualContentHeight makes everything go a bit down. Why?
Using InfySnip’s solution makes the whole objects dimensions and coordinates go crazy. Why?
Just another question: should I use this solutions both or just one of them? :slight_smile:

I don’t want to get into a huge discussion on content areas. We’ve written about this many times before, but basically your current config.lua is defining a content area that is exactly 320 points wide and 480 points high. This is a perfect fit for an iPhone 4 and some other older Android devices (Corona handles scaling it to 640x960 for instance on the iPhone 4). But every other device is going to have some extra space outside of this. If you’re background is designed to fit 320x480, then you will get black “letterbox” bars on two sides of the screen. For an iPhone 5, there will be 44 points of black at the top (I’m going to use portrait orientation for this discussion) and 44 points of black at the bottom since the actual screen when scaled to 320 points wide, is 568 points high (568-480 = 88 points of black space evenly divided along the screen).

In this configuration 0, 0 to Corona will be the left edge, but will be 44 points below the top. In other words, the top left corner is 0, -44. The bottom right corner will be 320, 568.

In this setup the various display functions that gets sizes will be:

display.contentWidth = 320

display.actualContentWidth = 320

display.contentHeight = 480 – what you have in your config.lua

display.actualContentHeight = 568 – the computed size.

On an iPad, its a bit different. You will find that due to it’s more square shape, the actual content width is 360, not 320 and you will have two letterbox bars on the sides that are 20 points each. The height will be an exact fit at 480 points. Thus the display values will be:

display.contentWidth = 320  – the size in your config lua

display.actualContentWidth = 360 – the computed size

display.contentHeight = 480

display.actualContentHeight = 480

Now top, left is -20, 0 and bottom right is 360, 480.

In either case, to hide the letterbox bars simply make your background big enough to fill the space and don’t put anything important in the “bleed” areas (i.e. those areas that will be off screen on some devices). Backgrounds should be 360x570 (other devices are a bit taller than the iPhone 5) and centered. On the iPad  some of the top and bottom will be hidden, on the phone some on the sides will be off screen.

Then you have to take into account, when positioning things, that the screen is bigger than the content area. You can use the two API calls:

display.screenOriginX – https://docs.coronalabs.com/daily/api/library/display/screenOriginX.html

display.screenOriginY – https://docs.coronalabs.com/daily/api/library/display/screenOriginY.html

to get the offset values of the top left from 0, 0 and use display.actualContentWidth and display.actualContentHeight to get to the bottom right corner as needed.

For many people, they want 0, 0 to be the top, left and display.contentWidth, display.contentHeight to be the bottom, right. This is where @InfiSnyp’s suggestion comes into play. We have a blog post called Modernizing Config.lua or some thing similar that covers this technique. It creates a content area that exactly fits the device you are on, but it will be slightly different on all screens. The beneift is that your right edge is always a .x of 0, your top edge is always a .y of 0 and so on. You can use display.contentCenterX and display.contentCenterY to center things or place them some offset from the center. For things that need to be near the edge you can position things relative to the edge.

An easy way to think about this is lets say you’re building a game and you want to show the score on the top right. You can position it at .x = 20 and .y = display.contentWidth - 60. Because a phone is narrower, the score will be closer to center than it will be on an iPad. On an iPad with the extra pixels on each side, that score will move towards the right edge on the bigger screen. 

If your background has a container where the score supposed to be, this will be a problem since the score moves based on the actual screen size. But you can solve this by having the score background be a separate asset and not part of the actual background and move that element with the score.

Both ways work. You have to think differently about how to get the screen size and were top,left and bottom,right end up.

In your example here:
 

W = display.actualContentWidth H = display.actualContentHeight mainMenu = widget.newScrollView { left = 0, top = 0, width = W, height = H, scrollWidth = 0, verticalScrollDisabled = true, backgroundColor = { 0, 0, 0}, listener = scrollListener } mainMenu.x = W / 2 mainMenu.y = H / 2

You don’t need to set top and left in the constructor since you immediately re-position the scrollView. If you wanted to just use top and left, and not re-position it, you could do instead:

W = display.actualContentWidth H = display.actualContentHeight mainMenu = widget.newScrollView { left = 0 + display.screenOriginX, top = 0 + display.screenOriginY, width = W, height = H, scrollWidth = 0, verticalScrollDisabled = true, backgroundColor = { 0, 0, 0}, listener = scrollListener }

Rob