Understanding letterbox scalling

I've replied to a post recently about how letterbox scalling works and since then I've bumped into a lot of people having trouble with the subject to whom I've been linking that old post.
As I came to the realization that it is quite an important subject and one that people don't understand too well, I'm creating a thread of its own, so here it goes:

<< Start of repost >>

Let's assume you're coding on portrait orientation.

You set your config.lua for a screen of 320x480 pixels, letterbox scalling, and position centered both vertical and horizontal.

1
2
3
4
5
6
7
8
9
application = {
    content = {
        width = 320,
        height = 480,
        scale = "letterbox",
        xAlign = "center",
        yAlign = "center",
    }
}

Now, when you create a background for the game, and you want to target iOS devices, so resolutions 320x480, 640x960 and 768x1024, you should do it like:

1
2
3
local bg = display.newImageRect("bg.png",360,480)
bg.x = display.contentWidth/2
bg.y = display.contentHeight/2

The resolution of the image files should be:

bg.png - 360x480
bg@2.png - 720x960, or even 768x1024 if you want it to look really good on iPad.

Why this 360 pixel width?

Well, the thing is that with letter box, the images on higher resolutions than defined on config.lua will be scaled to fit the screen, but they won't lose their aspect ratio, and that 320x480 rectangle you define on config.lua never goes out off screen.

Let's see some examples. Start by assuming we did things the "normal" way. You call background images as 320x480, what would happen is:

iPhone - No scalling, config.lua already defines a rectangle of the size of the screen, so it would look fine.

iPhone4 - Scaling by a factor of 2, so the ratio is the same. Would look fine too, it would use double resolution image (640x960)

iPad - the 320x480 rect would grow by a factor of 2.1333.., ending up at a size of 682x1024. Since the iPad has a 768x1024 screen, you would notice some black bars on the sides.

Now lets assume you did as I said and called background images as 360x480.

iPhone - No scalling since config.lua defines a rectangle of screen size. The background though is a bit bigger for the screen and has some extra width compared to screen size. Since the background is centered, you would actualy not see some pixels to the sides. More exactly, 360-320 = 40, so 20 pixels to each side.

iPhone4 - Exactly the same case but on higher resolution, scalling by a factor of 2, usage of high res images.

iPad - Once again it will grow by a factor of 2.133, so a 360x480 images would grow to 768x1024, completely filling the iPad screen. No black bars. Usage of high resolution images.

Basically, using this you create the backgrounds with some extra areas that will only be shown when the screen has a different ratio. The screen will always be filled. You have to keep in mind though that anything out of the 320x480 center rectangle of an image (considering low res images), will not show on some devices, so don't base you game in that areas, use it just for filling.

On Android the case is a bit different since the screen is actually taller (on portrait). So instead of having to increase width of background images from 320 to 360, you have to increase their height, from 480 to...
Well, considering all available android devices that number is 570.

In the case you want to completely support all resolutions of all phones/tablets available today, you should:

config.lua:

1
2
3
4
5
6
7
8
9
application = {
    content = {
        width = 320,
        height = 480,
        scale = "letterbox",
        xAlign = "center",
        yAlign = "center",
    }
}

Instantiation of images for backgrounds:

1
2
3
local bg = display.newImageRect("bg.png",360,570)
bg.x = display.contentWidth/2
bg.y = display.contentHeight/2

Low res images: 360x570 pixels
High res images: 720x1120 pixels

Remember that when you're coding though, you're coding for the rect defined on config.lua, so you're coding for a screen of 320x480. If for example on iPad you want to refer to the left of the screen it will not be 0, as 0 is a bit distant from the border, as iPad is wider and this 320x480 rect preserves aspect ratio. So you should actualy rely on some corona defined values to help you. For any device you can define the top, left, right and bottom points as:

Top:
local topY = display.screenOriginY

Right:
local rightX = display.contentWidth - display.screenOriginX

Bottom:
local bottomY = display.contentHeight - display.screenOriginY

Left:
local rightX = display.screenOriginX

Hope this helps everyone to understand letterbox a bit better!

<< End of repost >>

--
Manuel

原文地址:https://www.cnblogs.com/superchao8/p/2466223.html