Have game fit all res screens

Hey guys I feel so dumb right now cause I cant figure out how to make my game fit multiple devices screens and have every object be in the right position. Because everything turns out on the simulator but not on real devices.

level1.lua

local composer = require( "composer" ) local scene = composer.newScene() -- ----------------------------------------------------------------------------------------------------------------- -- All code outside of the listener functions will only be executed ONCE unless "composer.removeScene()" is called. -- ----------------------------------------------------------------------------------------------------------------- -- local forward references should go here -- ------------------------------------------------------------------------------- local physics = require("physics") -- "scene:create()" function scene:create( event ) local sceneGroup = self.view --make background------------------------------------- local bg = display.newImage("level1.png",239,160) bg:scale(1.25,1) physics.start() canmove = false motionx = 0; -- Variable used to move character along x axis speed = 6; -- Set Walking Speed health = 10 ammo = 5 local sheetData1 = { frames = { { name="Idle (10)\_70x69.png", x="148", y="60" ,width="35", height="59"}, { name="Idle (2)\_70x69.png", x="37", y="0" ,width="35", height="59"}, { name="Idle (3)\_70x69.png" ,x="0" ,y="60", width="35", height="58"}, { name="Idle (4)\_70x69.png" ,x="0", y="0" ,width="35", height="58"}, { name="Idle (5)\_70x69.png" ,x="74" ,y="0" ,width="35", height="58"}, { name="Idle (6)\_70x69.png" ,x="148", y="0", width="35" ,height="58"}, { name="Idle (7)\_70x69.png" ,x="111" ,y="60" ,width="35", height="58"}, { name="Idle (8)\_70x69.png", x="111", y="0", width="35", height="58"}, { name="Idle (9)\_70x69.png" ,x="74", y="60" ,width="35" ,height="59"}, }, sheetContentWidth = 256, sheetContentHeight = 128 } --1st image sheet local sheet1 = graphics.newImageSheet("sprites.png",sheetData1) --2nd images sheet local sheetData2 = { frames = { { name="Run (1)\_70x69.png", x="78", y="124", width="32", height="61"}, { name="Run (2)\_70x69.png", x="44", y="124" ,width="32", height="62"}, { name="Run (3)\_70x69.png" ,x="0", y="62" ,width="42", height="59"}, { name="Run (4)\_70x69.png", x="0", y="188" ,width="40" ,height="60"}, { name="Run (5)\_70x69.png" ,x="44" ,y="62" ,width="38" ,height="60"}, { name="Run (6)\_70x69.png", x="0" ,y="123" ,width="42", height="63"}, { name="Run (7)\_70x69.png" ,x="0", y="0" ,width="46" ,height="60"}, { name="Run (8)\_70x69.png" ,x="42", y="188" ,width="39" ,height="60"}, }, sheetContentWidth = 128, sheetContentHeight = 256 } local sheet2 = graphics.newImageSheet("sprites1.png",sheetData2) local sequenceData = { {name = "idle",sheet = sheet1,start=1,count=10,time= 600,loopCount = 0}, {name = "run",sheet = sheet2,start=1,count=8,time= 600,loopCount = 0} } local eric = display.newSprite( sheet1, sequenceData ) eric.x = display.contentWidth/2 ; eric.y = display.contentHeight/2 eric:play() physics.addBody(eric,"dynamic") local platform = display.newImage("platform.png",230,270) physics.addBody(platform,"static") --make buttons----------------------------------------- local btnR = display.newImage("buttonR.png",470,285) btnR:scale(0.3,0.3) local btnL = display.newImage("buttonL.png",10,285) btnL:scale(0.3,0.3) local btnUP = display.newImage("buttonUP.png",10,285) btnUP:scale(0.3,0.3) local sheild = display.newImage("shield.png",380,285) sheild:scale(0.08,0.08) ------------------------------------------------------- --make function for moving----------------------------- function btnL:touch() motionx = -speed; end btnL:addEventListener("touch",btnL) function btnR:touch() motionx = speed; local function swapSheet() eric:setSequence( "run" ) eric:play() end timer.performWithDelay( 200, swapSheet ) end btnR:addEventListener("touch",btnR) local function moveeric (event) eric.x = eric.x + motionx; end Runtime:addEventListener("enterFrame", moveeric) local function stop (event) if event.phase =="ended" then motionx = 0; end end Runtime:addEventListener("touch", stop ) local dialogue1 = display.newText("Welcome to the bunker let me teach you the basics!",240,50,"alienleague.ttf",20) local function removed1( event ) display.remove(dialogue1) end local function moveinstruc( event ) local instruc = display.newText("Use the arrows down below to move left and right",240,50,"alienleague.ttf",20) end local heart1 = display.newImage("heart.png",-20,20) heart1:scale(0.1,0.1) local heart2 = display.newImage("heart.png",20,20) heart2:scale(0.1,0.1) local heart3 = display.newImage("heart.png",60,20) heart3:scale(0.1,0.1) local function makeenemy( event ) local enemy = display.newRect(400,170,100,150) physics.addBody(enemy,"dynamic") local function enemyshoot(event) local bullet1 = display.newImage("bullet1.png",enemy.x,enemy.y) bullet1.rotation = 180 bullet1:scale(0.5,0.5) transition.to( bullet1, { time=3000, alpha=0,x=eric.x,y=eric.y } ) end timer.performWithDelay( 5000, enemyshoot,-1 ) end local function enemyshoot1(event) local bullet10 = display.newImage("bullet1.png",eric.x,eric.y) bullet10:scale(0.1,0.1) transition.to( bullet10, { time=3000, alpha=0,x=event.x,y=event.y } ) end Runtime:addEventListener("tap",enemyshoot1) --event Listners--------------------------------------- timer.performWithDelay( 5000, removed1 ) timer.performWithDelay( 6000, moveinstruc ) timer.performWithDelay( 8000, makeenemy ) --make sceneGroups------------------------------------- --make scenegroups------------------------------------- sceneGroup:insert(bg) sceneGroup:insert(platform) sceneGroup:insert(eric) sceneGroup:insert(btnUP) sceneGroup:insert(btnL) sceneGroup:insert(btnR) sceneGroup:insert(heart1) sceneGroup:insert(heart2) sceneGroup:insert(heart3) ------------------------------------------------------- ------------------------------------------------------- end

config.lua

application = { content = { width = 320, height = 480, scale = "letterBox", fps = 30, --[[imageSuffix = { ["@2x"] = 2, }, --]] }, --[[-- Push notifications notification = { iphone = { types = { "badge", "sound", "alert", "newsstand" } } }, --]] }

In your config.lua file try using one of these options

[lua]scale = “zoomStretch”[/lua]

[lua]scale = “adaptive”[/lua]

You can also not hard code all your objects into one place… You can try some corona math to help out with placing objects and so they stay in the correct place on every device.

–SonicX278

Just to elaborate on what SonicX278 has said (since this is the newbie forum):  

Instead of placing your objects with fixed numbers like this:

myobject.x = 150 myobject.y = 200

Place them by using fractions of the screen space:

myobject.x = display.contentWidth \* 0.5 myobject.y = display.contentHeight \* 0.33

One thing to keep in mind is that the display.contentWidth and display.contentHeight are based on the values you enter in your config.lua file. If you run the game on a device with an aspect ratio that doesn’t match your config file, you’ll have some “extra” space at the edges of the screen. In those cases, I tend to position things using the “real” edges of the screen and screenSize:

--get the value for the far left of the screen minVisX = display.screenOriginX --get the value for the far right of the screen maxVisX = display.viewableContentWidth + -1\* display.screenOriginX --get the value for the top of the screen minVisY = display.screenOriginY --get the value for the bottom of the screen maxVisY = display.viewableContentHeight + -1\* display.screenOriginY --these are the "real" full width and height of the screen \_W = maxVisX - minVisX \_H = maxVisY - minVisY 

Then if I want to position something at say, 1/3 of the way across the screen I do this:

myobject.x = minVisX + (\_W \* 0.3)

Perhaps this is too much work for you, but I simply grab the device’s resolution and manage the direct placement and size of every object based upon each device’s resolution. This seems to be time consuming at first - here is, for example, how I would display text in the middle of the screen. Also, FYI, I use V=variables.lua to define all of my own globals.

V.W = display.viewableContentWidth
V.H = display.viewableContentHeight

obj=display.newtext(“my text here”,(7777),V.H*.5,font,fontSize)  —I use (7777) when I don’t yet define a value when the obj is made

obj.x = (V.W*.5)-(obj.width*.5)  --this code centers the object on the screen

It may seem like a lot of work, but after a while, it comes out of me quite easily and consistently - as fast as I can type. If I want something to display at a point in the screen that is 10% from the top, I would use V.H*.1 - or 70% from the top use V.H*.7

The point here is that I’m able to use the entire real-estate. This only has trouble working if you attempt to manage the height and width of bitmapped images of words that get stretched on wider devices. For this reason, I stick with using Corona to render all text - and in fact, have developed my own outline routine and use capture or snapshot features in Corona to convert rendered text on the fly into a bitmap that will appear properly.

The other issue this concept involves is that you can’t use composer. Instead, you must manually position everything. However, I’ve found that using graph paper to create a layout in advance makes this process easy enough. And often when positioning items, I reference the post-placement values of other objects in order to insure relative positioning on any device with any resolution. It works great and now that I’ve been doing it for many months, its second nature. At some point, I plan to create my own version of composer which will be designed with this concept in mind - of course, it will be slowly than anything built into Corona. But with CPU speeds of mobile devices continuing to increase, I’ll keep to this practice to insure every App made fits properly and perfectly on any other device.

I’m not sure about recommending “adaptive” for games. Adaptive gives you different amounts of screen real estate depending on the device. It’s really more for business and utility apps. Games need more of a fixed content area.

Just throwing this out there… But his problem about this was solved. But its good getting suggestions.

–SonicX278

Hi Rob,

I agree with you that “Adaptive” requires a lot more work - and in most cases for games, is likely not preferred. It should really only be considered when the additional real estate substantially improves the user experience on wider devices. (i.e. Kindle Fire 9" compared to an iPad). That’s why I use it.

How does this whole conversation play into the Corona Composer? Can you place objects at certain percentages of the screen size like you can in other scene builders?

If you’re talking about Corona Composer GUI, its probably more of a traditional x, y positioning system. The standard 320x480 fixed screen is guaranteed to have the 320x480 area on the screen on all devices. 

Consider a landscape app (which you would most likely build with CCGUI). If you’re on a 16:9 device (typical modern phone), the screen will be 568x320. The 480 side will be centered in the 568, so you have 44 extra points to the left and 44 extra points to the right. The game plays within the 480 points and your background just needs to fill the extra space.  On an iPad, the 480 will fill the width, but you’re going to have extra space at the top and bottom that your action wouldn’t take place in.

Rob

In your config.lua file try using one of these options

[lua]scale = “zoomStretch”[/lua]

[lua]scale = “adaptive”[/lua]

You can also not hard code all your objects into one place… You can try some corona math to help out with placing objects and so they stay in the correct place on every device.

–SonicX278

Just to elaborate on what SonicX278 has said (since this is the newbie forum):  

Instead of placing your objects with fixed numbers like this:

myobject.x = 150 myobject.y = 200

Place them by using fractions of the screen space:

myobject.x = display.contentWidth \* 0.5 myobject.y = display.contentHeight \* 0.33

One thing to keep in mind is that the display.contentWidth and display.contentHeight are based on the values you enter in your config.lua file. If you run the game on a device with an aspect ratio that doesn’t match your config file, you’ll have some “extra” space at the edges of the screen. In those cases, I tend to position things using the “real” edges of the screen and screenSize:

--get the value for the far left of the screen minVisX = display.screenOriginX --get the value for the far right of the screen maxVisX = display.viewableContentWidth + -1\* display.screenOriginX --get the value for the top of the screen minVisY = display.screenOriginY --get the value for the bottom of the screen maxVisY = display.viewableContentHeight + -1\* display.screenOriginY --these are the "real" full width and height of the screen \_W = maxVisX - minVisX \_H = maxVisY - minVisY 

Then if I want to position something at say, 1/3 of the way across the screen I do this:

myobject.x = minVisX + (\_W \* 0.3)

Perhaps this is too much work for you, but I simply grab the device’s resolution and manage the direct placement and size of every object based upon each device’s resolution. This seems to be time consuming at first - here is, for example, how I would display text in the middle of the screen. Also, FYI, I use V=variables.lua to define all of my own globals.

V.W = display.viewableContentWidth
V.H = display.viewableContentHeight

obj=display.newtext(“my text here”,(7777),V.H*.5,font,fontSize)  —I use (7777) when I don’t yet define a value when the obj is made

obj.x = (V.W*.5)-(obj.width*.5)  --this code centers the object on the screen

It may seem like a lot of work, but after a while, it comes out of me quite easily and consistently - as fast as I can type. If I want something to display at a point in the screen that is 10% from the top, I would use V.H*.1 - or 70% from the top use V.H*.7

The point here is that I’m able to use the entire real-estate. This only has trouble working if you attempt to manage the height and width of bitmapped images of words that get stretched on wider devices. For this reason, I stick with using Corona to render all text - and in fact, have developed my own outline routine and use capture or snapshot features in Corona to convert rendered text on the fly into a bitmap that will appear properly.

The other issue this concept involves is that you can’t use composer. Instead, you must manually position everything. However, I’ve found that using graph paper to create a layout in advance makes this process easy enough. And often when positioning items, I reference the post-placement values of other objects in order to insure relative positioning on any device with any resolution. It works great and now that I’ve been doing it for many months, its second nature. At some point, I plan to create my own version of composer which will be designed with this concept in mind - of course, it will be slowly than anything built into Corona. But with CPU speeds of mobile devices continuing to increase, I’ll keep to this practice to insure every App made fits properly and perfectly on any other device.

I’m not sure about recommending “adaptive” for games. Adaptive gives you different amounts of screen real estate depending on the device. It’s really more for business and utility apps. Games need more of a fixed content area.

Just throwing this out there… But his problem about this was solved. But its good getting suggestions.

–SonicX278

Hi Rob,

I agree with you that “Adaptive” requires a lot more work - and in most cases for games, is likely not preferred. It should really only be considered when the additional real estate substantially improves the user experience on wider devices. (i.e. Kindle Fire 9" compared to an iPad). That’s why I use it.

How does this whole conversation play into the Corona Composer? Can you place objects at certain percentages of the screen size like you can in other scene builders?

If you’re talking about Corona Composer GUI, its probably more of a traditional x, y positioning system. The standard 320x480 fixed screen is guaranteed to have the 320x480 area on the screen on all devices. 

Consider a landscape app (which you would most likely build with CCGUI). If you’re on a 16:9 device (typical modern phone), the screen will be 568x320. The 480 side will be centered in the 568, so you have 44 extra points to the left and 44 extra points to the right. The game plays within the 480 points and your background just needs to fill the extra space.  On an iPad, the 480 will fill the width, but you’re going to have extra space at the top and bottom that your action wouldn’t take place in.

Rob