Cannot get letterbox scaling to work (Android)

For some reason I’ve suddenly started to have problems getting the letterbox scaling to work properly.

I use the same setting as usual, scaling the entire thing to 800x1300 using the following config.lua:

application = { content = { width = 800, height = 1300, scale = "letterbox", xAlign = "center", yAlign = "center", fps = 60, } }

I have always thought (and experienced) that this would create a virtual drawing area of 800x1300 pixels with black bars outside this (if necessary).

But with my last project I have obviously somehow messed this up. Please consider the following main.lua:

-- Content auto-scaled to 800 x 1300 \_W = display.contentWidth \_H = display.contentHeight print("Virtual screen size (" .. \_W .. " x " .. \_H .. ")") -- Draw background local bg = display.newRect(\_W/2, \_H/2, \_W, \_H) bg:setFillColor(0.3,0.6,0.2) -- Draw top bar 1 tb = display.newRect(0, 0, \_W/2, 80) tb.anchorX = 0 tb.anchorY = 0 tb:setFillColor(0.2,0.4,0.9,0.85) -- Draw top bar 2 tb = display.newRect(\_W/2, -50, \_W/2, 80) tb.anchorX = 0 tb.anchorY = 0 tb:setFillColor(0.9,0.4,0.2,0.85)

This snippet reports (correctly) that the virtual drawing area is 800x1300.

Then I fill the entire background with this line:

local bg = display.newRect(\_W/2, \_H/2, \_W, \_H)

And place a blueish top bar like this:

tb = display.newRect(0, 0, \_W/2, 80) tb.anchorX = 0 tb.anchorY = 0 tb:setFillColor(0.2,0.4,0.9,0.85)

Then I add a orange top bar, but this time I set the y position to a negative value (-50):

tb = display.newRect(\_W/2, -50, \_W/2, 80) tb.anchorX = 0 tb.anchorY = 0 tb:setFillColor(0.9,0.4,0.2,0.85)

To my surprise this was drawn outside of the letterbox (see attachment).

Is this really how this is supposed to work with the letterbox scaling? Is there a bug? Or is it me who have messed up (as usual :P )?

Hi @runewinse,

Yes, this seems normal. Letterbox will make the entire content area fit on (any) screen, and the top-left point of that content area will be 0,0 as usual. It’s your task to fill those letterbox regions as you see fit. One trick I use to gather the width and height of the letterbox regions is this:

[lua]

local letterboxWidth = (display.actualContentWidth-display.contentWidth)*0.5

local letterboxHeight = (display.actualContentHeight-display.contentHeight)*0.5

[/lua]

Then, you can add or subtract these values to whatever object to position it against the edge of the screen. And, fortunately, you can easily test this in the Simulator and switch device skins to see how it works.

Hope this helps,

Brent

I may have misunderstood something so please let me get this 100% clear:

The letterbox scaling system will not prevent things from being drawn outside of it and this is by design?

So if I write a vertical scroller game and start drawing objects above the screen with negative y coordinates (as is the only way of not making them suddenly appear) I will have to mask them manually with a black rectangle or something?

Hi @runewinse,

Yes, this is true, but that’s by design and it applies to all scaling modes. The content area merely represents the overall stage, but you can also draw or position things outside of this (and sometimes you would want to, i.e. start incoming enemies somewhere off the screen, or keep them in some kind of hidden area far outside the content area and drop them on-screen only when they’re needed).

You could, of course, use “zoomEven” scale mode which will makes sure that the entire screen is filled (no letterbox bars). However, on some screens, some content will be pushed off (and lost to the user’s eye) on two sides.

If you do use letterbox (and that’s is my personal favorite for most projects) you should never leave those letterbox bars empty, nor mask them and leave them black. The app stores may reject apps like these because they appear to “not use the entire screen”, and that makes for a poor user experience from their standpoint, as if you’re not utilizing all of the amazing sharp screen that you’ve been given to use. :slight_smile:

Brent

Ok, thanks for the info. I made a top status bar and made this at 0,0 (letterbox coordinates). This meant that the scrolling objects from the top showed a bit above the status bar and that didn’t look very good…

I’ve now placed the top bar at y = -letterboxHeight instead, using the available space a bit better (and avoiding those pesky objects from showing above).

Hi @runewinse,

Yes, this seems normal. Letterbox will make the entire content area fit on (any) screen, and the top-left point of that content area will be 0,0 as usual. It’s your task to fill those letterbox regions as you see fit. One trick I use to gather the width and height of the letterbox regions is this:

[lua]

local letterboxWidth = (display.actualContentWidth-display.contentWidth)*0.5

local letterboxHeight = (display.actualContentHeight-display.contentHeight)*0.5

[/lua]

Then, you can add or subtract these values to whatever object to position it against the edge of the screen. And, fortunately, you can easily test this in the Simulator and switch device skins to see how it works.

Hope this helps,

Brent

I may have misunderstood something so please let me get this 100% clear:

The letterbox scaling system will not prevent things from being drawn outside of it and this is by design?

So if I write a vertical scroller game and start drawing objects above the screen with negative y coordinates (as is the only way of not making them suddenly appear) I will have to mask them manually with a black rectangle or something?

Hi @runewinse,

Yes, this is true, but that’s by design and it applies to all scaling modes. The content area merely represents the overall stage, but you can also draw or position things outside of this (and sometimes you would want to, i.e. start incoming enemies somewhere off the screen, or keep them in some kind of hidden area far outside the content area and drop them on-screen only when they’re needed).

You could, of course, use “zoomEven” scale mode which will makes sure that the entire screen is filled (no letterbox bars). However, on some screens, some content will be pushed off (and lost to the user’s eye) on two sides.

If you do use letterbox (and that’s is my personal favorite for most projects) you should never leave those letterbox bars empty, nor mask them and leave them black. The app stores may reject apps like these because they appear to “not use the entire screen”, and that makes for a poor user experience from their standpoint, as if you’re not utilizing all of the amazing sharp screen that you’ve been given to use. :slight_smile:

Brent

Ok, thanks for the info. I made a top status bar and made this at 0,0 (letterbox coordinates). This meant that the scrolling objects from the top showed a bit above the status bar and that didn’t look very good…

I’ve now placed the top bar at y = -letterboxHeight instead, using the available space a bit better (and avoiding those pesky objects from showing above).