Adaptive, display content, positioning question

@Brent

I have both devices (s8 & s8+) on which I test. I keep buying and selling devices and while I have them in my hands I test them with my app.

I don’t personally have one and I’m out of the office at the moment. Doesn’t that device have some kind of “tall mode” software switch option which toggles between what is displayed?

Brent

@Brent

Settings > display > full screen apps

If my memory does not fail me, I’m not in my home studio right now.

Can I reset the config after the app is loaded?

I was thinking I’ve seen this before in an app. Where the user can set the scale mode.

If not then if the user doesn’t want zoomStretch/letterbox, I could let them decide? Maybe I could put  “note: Close the App and reload to letterbox/zoomstretch”. And I could read letterbox or zoomstretch out of a saved file in the Documents directory?  Because both seem to work well in my game. I might as well give the user a choice.

This is not correct.  You can scale sprites to get any ‘size’ that you want.

You cannot reset the config after it’s loaded. You should not (and cannot for desktop apps) do operations in config.lua*. We even discourage using zoomStretch because it has the potential to seriously distort the screen. I know another Corona developer is trying to do this, but I’ve never seen other apps offer such a setting.

* Many people do compute the aspect ratio in config.lua and dynamically adjust the width and height to make the content area fit the screen. There are pros and cons to this method, but more importantly it doesn’t work for desktop builds and is taking advantage of an a feature that just happens to work and could change in the future.

Without knowing what you’re trying to do, it’s hard to advise what the best course of action for you. I’m going to be updating one of my games in the App Store today and it uses a computed config.lua, but it’s a game that works well for. The new game I’m working on, a computed config.lua would be a really bad idea because it would affect game play.

For many developers, what config.lua does and how Corona adapts that to various screens may seem like hard to understand magic, but it’s really not.

What config.lua does is define an invisible rectangle on the screen. By default that rectangle gets centered, but you can move it around depending on what you want to accomplish.  Most people make that rectangle a 1:1.5 (2:3) aspect ratio, meaning that it’s 1.5x longer than it is wide (I’ll do all of this for portrait apps since you always specify portrait dimensions in config.lua).  If you set your width to 320 in config.lua, your 1.5x height would be 480.  Depending on your screen you may have extra space on either side of the box while the opposite side should be flush to those edges.  If you’re on a phone, or TV (or full screen desktop) you’re likely going to have more space on the top and bottom of the box. If you’re on an iPad or other more square tablets, that extra space will be on the sides.

What frustrates many is that 0, 0 isn’t the top, left of the screen and display.contentWidth, display.contentHeight is no longer the right, bottom.  

There are a couple of solutions to this and it depends on the type of game/app you’re making. If distance between objects **will not** affect game play (such as my trivia game), you could shift the virtual screen box to be aligned to the top, left, which would make 0, 0, the top left and then don’t use display.contentWidth, display.contentHeight, but instead use display.actualContentWidth, display.actualContentHeight and you now have the same effect as computing the aspect ratio.

If your game is one where distance between objects matters, think angry birds and the distance between the slingshot and the pigs, or in my new game where the distance between my player’s ship and the enemies appearing on the screen would make the game easier on a phone if the space is stretched out and harder on an iPad when they start closer together, this type of config is bad. 

In this case, when you need to reference the bottom, right,  you can still use display.actualContentHeight, display.actualContentWidth, but you need to add display.contentOriginX, display.contentOriginY to anything you’re positioning around the edges of the screen. You can start your sling shot at X pixels and put the pigs near display.contentWidth.  Then depending on  your device that extra space just becomes extra background and doesn’t factor into game play. But you can position your UI elements using the display.contentOriginX, Y values.

The trick is to make sure you background is big enough to work on all screens, which means part of it will most likely be off screen depending on the device. Don’t build UI chrome into the background since you need to move that stuff around.

Rob

If I was to do a desktop or iTV/AmazonTV build, it is looking like I would most likely split my code base into two builds specifically for this. Especially if I am not to do 

My game is a pixel game.  Meaning I render my assets small, and scale them x2. With a pixel game, having pixels align properly is one of the most important aspects of having a pixel game.  A pixel game is a popular method of making 2D games.

 that just happens to work and could change in the future.

I understand that a lot of people in the Corona community, especially the Corona engineers, have really expressed that they do not create many pixel graphic games with finite borders.  When I mention a Pixel on my screen, I realize it is not literally a ‘pixel’ on the screen. It is a collection of pixels made to represent the scaled ‘pixel’. So unless the aspect ratio meets 1:1 on my game will never match exactly with zoomstretch. It will be elongated in y slightly for most devices. I typically can compensate for this with making my graphics slightly elongated in X and the affect is not that bad.

My game has taken years to make for a variety of reasons (outside of working on it) and there is no ‘just dont make it like that’ option at this point. I literally have thousands of users waiting on my game.   

Without knowing what you’re trying to do, it’s hard to advise what the best course of action for you

You can go here to see screenshots and gifs of my game in action, this should give you a clearer understanding of what I am doing. My game does not have floating graphics ui for obvious reasons. Having control of the borders of my game IS the primary importance of a pixel game of my style.

Currently both methods seem to work fine for my game, while the zoomStretch, seems to work the best but letterbox does seem to be workable as well. As long as I avoid many round circles filling the entire screen with my pixel game zoomstretch seems to work the best for now. 

One good thing about my game is that I have moved all UI coordinates into tables. So I can easily(relatively) set configurations of X,Y coordinates for letterbox if I was to make a desktop version. In doing this I have found that it can also ‘work’ for phones with that 2:1 aspect ratio, although I end up with very large blank areas of letterbox that are more extreme in the portrait mode for a game like this.

While I have developed my game to be adaptable to letterbox, I really hope it is not in the plan to get rid of zoomstretch for Corona because ‘most’ developers do not use it. It would severely affect my business in the long run.

I’ve not heard any talk about removing “zoomStretch”. 

wacky stuff fwiw, i’ll likely “take heat” for even mentioning this, but it is possible.  (i’m also not suggesting it’s recommended, because it isn’t easy or intuitive, and corona support would likely just shrug you off if they knew you were doing this)

you can recreate for yourself any of the scale modes by omitting content dimensions from config.lua – you’ll then be using device dimensions… at least initially.  now size and position the stage however you wish to accomplish an equivalent scaling to having set content dimensions in config.lua.

for example, first calc x/y scales:

local xscale = desiredContentWidth / device.pixelWidth local yscale = desiredContentHeight / device.pixelHeight

then figure out how you’ll use them based scale method:

if (desiredScaleMethod == "zoomStretch") then -- nop, use x/y scales as is, anamorphic elseif (desiredScaleMethod == "letterbox") then -- fit longer axis, letterbox shorter axis xscale = math.max(xscale, yscale) yscale = xscale elseif (desiredScaleMethod == "zoomEven") then -- fit shorter axis, bleed longer axis xscale = math.min(xscale, yscale) yscale = xscale end

then adjust the stage to match

local stage = display.getCurrentStage() stage.width, stage.height = desiredContentWidth, desiredContentHeight -- corona's notion of content scale is backwards to what is needed here stage.xScale, stage.yScale = 1.0/xscale, 1.0/yscale

…et cetera, because there’s more work to do, like figuring out how you want to center the stage on the device (and what your resulting origins will be) or calcing for convenience the resulting equivalents to viewable/actual contentWidth/Height.  but all of that is just a bit of basic math, and you can even stuff those derived values back into display.* if you wish to make it backwards compatible. (just don’t mess with pixelWidth/Height).

you’ll also need to monitor resize/orient events and do whatever dynamic recalc in response to those events, since you’d no longer be relying on corona to do it for you.

but finally, once all is working, you can dynamically set any scale mode or content dimensions that you please at runtime.