Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

The result of screen resolution cannot be passed beyond main.lua after the build is built.
Started by OlinaChang Jan 21 2020 04:18 PM

7 replies to this topic
[TOPIC CONTROLS]
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

OlinaChang

[GLOBAL: userInfoPane.html]
OlinaChang
  • Observer

  • 25 posts
  • Corona SDK

After my picture book app is almost done, I got an idea to make a little more: to make the illustration/animation of each page to scale with the screen width of the device. I planed this to show entire composition of each illustration with animation in each page. Fortunately, I organized the illustration and animation in one display group. Here is the structure of my app:

8X9U39f.png

 

Somehow I made the content of my app as 960x 640, and scale = "zoomEven" in the year of 2017. Each illustration with animation is 640x 640, align on the top. For the idea of scaling illustration according to the device resolution, I wrote a deviceRatio() function in main.lua

-----------------------------------------------------------------------------------------
--
-- main.lua
--
-----------------------------------------------------------------------------------------
-- include the Corona "composer" module
local composer = require("composer")

-- hide the status bar
display.setStatusBar( display.HiddenStatusBar )
display.setDefault("background", 1, 0.6823, 0.78823)	-- light pink BG

-- Removes bottom bar on Android https://docs.coronalabs.com/api/library/native/setProperty.html 
if system.getInfo( "androidApiLevel" ) and system.getInfo( "androidApiLevel" ) < 19 then
    native.setProperty( "androidSystemUiVisibility", "lowProfile" )
else
    native.setProperty( "androidSystemUiVisibility", "immersiveSticky" ) 
end

-- get resolution scaleFactor for illustration
function deviceRatio()
	local ratio = display.pixelHeight/display.pixelWidth
	local scaleFactor
	if ratio <=1.5 then scaleFactor = 1
		elseif ratio == 1.6 then scaleFactor = 0.9375
		elseif ratio == 1.666 then scaleFactor = 0.9
		elseif ratio >1.7 and ratio <= 1.8 then scaleFactor = 0.846
		elseif ratio >2 then scaleFactor = 0.6927
	end
	print("scaleFactor in main", scaleFactor)
	return scaleFactor
end

local scaleFactor = deviceRatio()

composer.setVariable("scaleFactor", scaleFactor)
print("scaleFactor in main II", scaleFactor)

-- load title/cover screen
composer.gotoScene( "coverPage", "fade", 300)

I get the scaleFactor and pass it to page01.lua to scale the display group which contains illustration and animation of each page. Everything worked perfectly on Corona Simulator as I switched among different resolution and devices. However, after I made a build and ran on my Android phone, it showed a Runtime Error right away when I touch the coverPage.

 

Runtime Error

 

C:\ ....\picBookProject\page01.lua:200: bad argument#1 to 'scale' (number expected, got nil)

-- page01.lua
-- -----------------------------------------------------------------------------------
local composer = require( "composer" )
local widget = require( "widget" )
local scene = composer.newScene()

local pages = require("data")  -- load the pages "module" of page information
...

local backGroup -- add mainImage(illustration #.png) in, otherwise mainImage are keeping in front of buttons 
local mainGroup
local animGroup -- one illustration with animation
local uiGroup

...

-- -----------------------------------------------------------------------------------
-- Scene event functions
-- -----------------------------------------------------------------------------------

-- create()
function scene:create( event )

	local sceneGroup = self.view
	-- Code here runs when the scene is first created but has not yet appeared on screen
	
	-- Set up display groups
	backGroup = display.newGroup()
	sceneGroup:insert( backGroup )
	
	local illuScale = composer.getVariable("scaleFactor")
	print("illuScale", illuScale)  -- to confirm that I got the scaleFactor value
	local animGroup = pages[101].animGroup
		  animGroup.anchorChildren = true
		  animGroup.anchorX = 0
		  animGroup.anchorY = 0
		  animGroup:scale(illuScale, illuScale)
		  animGroup.x = display.screenOriginX
		  animGroup.y = display.screenOriginY
	
	sceneGroup:insert(animGroup)

	mainGroup = display.newGroup()
	sceneGroup:insert( mainGroup )

	uiGroup = display.newGroup()
	sceneGroup:insert( uiGroup )

...

I have been thinking maybe I should put the deviceRatio function in config.lua. However, if doing so, I cannot pass the scaleFactor to the other lua with composer.setVariable()  and composer.getVariable.

Any idea why the scaleFactor could be passed in Corona Simulator, but not on build ? What should I do? 

Thank you in advance. :)
 



[TOPIC: post.html]
#2

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,641 posts
  • Corona SDK

** UPDATE ** I misread this.  You want to have this behavior ONLY in the simulator...
 
If you have SSK in your project, you can just do this:
(https://github.com/roaminggamer/SSK2)
 

local scaleFactor = onSimulator and 1 or deviceRatio()  -- in main.lua

Then you can still use scaleFactor, but have it default to a known value when not running the simulator.


  • OlinaChang likes this

[TOPIC: post.html]
#3

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,641 posts
  • Corona SDK

If you don't want to use SSK, you can just detect you're on the simulator like this:

local platformEnvironment     = system.getInfo("environment")

_G.onSimulator        = platformEnvironment == "simulator"


  • OlinaChang likes this

[TOPIC: post.html]
#4

Michael Flad

[GLOBAL: userInfoPane.html]
Michael Flad
  • Contributor

  • 268 posts
  • Corona SDK

Your problem is your scaleFactor calculation as it only calculates a value at all for some display sizes. In your case, your Android devices has a resolution that does not result in a calculated value thus the variable is never set to a number in your main.lua and that's why you get the nil error in page01.lua.
 
local ratio = display.pixelHeight/display.pixelWidth
local scaleFactor
if ratio <=1.5 then scaleFactor = 1
    elseif ratio == 1.6 then scaleFactor = 0.9375
    elseif ratio == 1.666 then scaleFactor = 0.9
    elseif ratio >1.7 and ratio <= 1.8 then scaleFactor = 0.846
    elseif ratio >2 then scaleFactor = 0.6927
end
 
You can check the if/elseifs for what I mean.
You don't calculate the scaleFactor at all for the following ratio values
> 1.5 and < 1.6
> 1.6 and < 1.666
> 1.666 and <= 1.7
> 1.8 and <= 2
 
 
Here's a function to calculate the correct scale value that guarantees to have a given rect (width, height) visible within a defined other area (otherWidth, otherHeight)
 
-- put this somewhere in your main
local function calcScale( width, height, otherWidth, otherHeight )
    local newWidth = width * (otherHeight/height)
    local newHeight = height * (otherWidth/width)
 
    if newWidth > otherWidth then
        return otherWidth/width
    else
        return otherHeight/height
    end
end
 
 
-- and calc your scale factor like so
local scaleFactor = calcScale( 640, 640, display.pixelWidth, display.pixelHeight )
 
Depending on the scale settings in config.lua and the result you want you may need to use the contentWidth and contentHeight or the actualContentWidth and actualContentHeight values from the display objects instead of pixelWidth and pixelHeight.
 

  • roaminggamer, Alan PlantPot, XeduR @Spyric and 1 other like this

[TOPIC: post.html]
#5

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Corona Geek

  • 1,176 posts
  • Corona SDK

Michael Flad's approach is precisely the way to go.

Constructing lengthy conditional statements gets difficulty to manage after a while and you'll run into issues if there is an outlier that doesn't meet with the predetermined criteria. Having a single universal solution is both easier to manage and less prone to bugs.


  • OlinaChang likes this

[TOPIC: post.html]
#6

OlinaChang

[GLOBAL: userInfoPane.html]
OlinaChang
  • Observer

  • 25 posts
  • Corona SDK

Hi all, thank you for all your reply. I am glad I level up my coding of function again. However, I am still digesting Michael Flad's code.

 

I put the code in and built a build, it worked. However, the scaleFactor changes from 0.846 to 1.6875 when Simulator view as 1080x1920. So far only Viewing as 640x960 is correct (scaleFactor =1). I am trying to figure out what's wrong.

 

By the way, I think the resolution of my Sony Xperia XZ Premium is 2160x3840 (1.77777) according to the screenshot image which is taking by default device screen capture button. I wonder if this means pixelWidth = 2160 and pixelHeight = 3840 ? Does using screenshot to verify the device resolution is correct? :huh:

@roaminggamer
No no no. I was a little ambitious. :lol:  Not only on Corona Simulator. I wish to fit most devices. Kinda like making RWD for device. I will check out your SSK. I have known of your SSK for a while when google question around. But most of time I don't understand the code, maybe because I haven't got that level yet.

 

@Michael Flad
Thank you for your code. I am still digesting it.

When I tired to observe if any way to achieve my idea, I arranged this diagram.
BPbdNQv.png
Then I use the following code to observe my situation.
 

print("display.topStatusBarContentHeight", display.topStatusBarContentHeight)
print("display.contentScaleX", display.contentScaleX)
print("display.contentScaleY", display.contentScaleY)
print("display.pixelWidth", display.pixelWidth )
print("display.pixelHeight", display.pixelHeight )
print("aspact ratio", display.pixelHeight / display.pixelWidth)
print("for Dynamic Image Selection", display.pixelWidth / display.actualContentWidth )		-- suggested by Dynamic Image Selection
print(" -------------- ")
print("display.contentWidth", display.contentWidth)
print("display.contentHeight", display.contentHeight)

print("display.screenOriginY", display.screenOriginY)
print("display.screenOriginX", display.screenOriginX)
print("display.viewableContentWidth", display.viewableContentWidth, " if letterbox, no pillar area")
print("display.viewableContentHeight", display.viewableContentHeight)

print("display.actualContentWidth", display.actualContentWidth )		-- if letterbox scale, returns the content width, including the letterbox area. -- if zoomEven scale, = display.viewableContentWidth property.
print("display.actualContentHeight", display.actualContentHeight )		-- if letterbox scale, returns the content height, including the letterbox area. -- if zoomEven scale, = the display.viewableContentHeight property.
print("aspact ratio", display.actualContentHeight / display.actualContentWidth)

And then, I have to use pixelWidth and pixelHeight, otherwise I will get pillar bars when viewing as 4:3 (1.3333..) device.

 

Finally, I did some calculation.... (I wish I used 16:9 instead of 4:3 since it seemed rare to meet 4:3 device )
U2Fu4qw.jpg

Actually, when I made the composition of illustration, I did consider that left and right sides were cropped when it's 16:9 (1.7777). Now if I don't want them to be cropped, I can just use scaleFactor = 0.846 to make 640x640 to shrink the display group and fit it all in 1080x1920 (1.7777) device, and ignoring the other resolution. However, I just think it's almost there... to make RWD on our favorite Corona~~~

Maybe in the future, starting our project with letterbox and 16:9, instead of 4:3, is better? :ph34r:
 

 



[TOPIC: post.html]
#7

SGS

[GLOBAL: userInfoPane.html]
SGS
  • Corona Geek

  • 2,205 posts
  • Corona SDK

Designing for 16:9 letterbox is a good place to start... you can then fill the blanks for tall/wide devices.

 

It is advisable to constrain a single dimension (normally height for portrait) in config.lua.  Pick a static height and calculate the width.

 

For example,

 

        width = 960,
        height = math.floor(960 * display.pixelHeight/display.pixelWidth),

Then you do not have to worry too much about scaling.


  • OlinaChang likes this

[TOPIC: post.html]
#8

OlinaChang

[GLOBAL: userInfoPane.html]
OlinaChang
  • Observer

  • 25 posts
  • Corona SDK

Hi all,

After I asked a friend coder about the logic of Michael Flad's solution, I understood it! Then I was trying to focus on fixing the scale issue. After I figured out why the scale was wrong, I found that, originally, in the very beginning, I just wanted to make the animation displayGroup.width = display.actualContentWidth. However,  since displayGroup is a special type of display object, I cannot assign its width this way. Therefore I was trying to change its size with object:scale(), and started looking for the "scaleFactor". Eventually, it has gone too far.

 

Now I just need one line:

local scaleFactor = display.actualContentWidth/640

This 640 should be the content width I set in config.lua, I think. or maybe I should use

local scaleFactor = display.actualContentWidth/display.contentWidth

Now it's all set!!! The burned build also works, although I only have two Sony mobile devices to test :P

Still thank you for all your time and reply. Thank you very very much! <(_ _)>

 




[topic_controls]
[/topic_controls]