Is corona cannon still a good reference for beginners.

I am going through the code of corona cannon which is an official corona sample game.

I wanted to know if anything is outdated in it. Or if there are new ways to do something which has been done in the game. I also see that the config.lua has a dynamic config.

local normalW, normalH = 640, 960

if not display then return end – This is needed for dekstop app

local w, h = display.pixelWidth, display.pixelHeight

local scale = math.max(normalW / w, normalH / h)

w, h = w * scale, h * scale

application = {

    content = {

        width = w,

        height = h,

        scale = ‘letterbox’,

        fps = 60,

        imageSuffix = {

              [’@2x’] = 2,

        }

    }

}

I went through the forum about dynamic config and found out that its not such a good idea to use, as it leads to confusion. But this config seems to work well with iphoneX or samsung S9 very well, since the background is a gradient.

I know this is out of context:-

Is there a way i could use content width=320 and height=480, and make it work on extreme screen displays(iphoneX , s9, etc.), as many latest phones seems to have aspect ratio of 2:1, as well as normal (pre iphoneX era phones). i.e using background having resolution in range of 360*570, 720*1140, 1440, 2280.

Or should i have another set of background image since these extreme display screens need 360*640 resolution images. And write a code to check and utilize the 360*640 resolution images for extreme screens.

So can anyone of you showcase your workaround to handle both normal and extreme screen sizes.

Thank you

From what I remember, it is a great sample app and clearly demonstrates how you could create an angry birds style game. There are several other ways that I can come up with off the top of my head for creating such a game, so it really comes down to your personal preference or style. Still, that being said, it isn’t a complete game and there are some things that should be addressed if you plan on creating a commercial game like that, but it is a great sample app.

Dynamic content scaling is something that you definitely should use and it makes your life a lot easier. The thing to remember is to design your game accordingly. You should probably read https://docs.coronalabs.com/guide/basics/configSettings/index.html.

I tend to use 960x640 as my default resolution as that area is generally visible for most modern devices. Then, for backgrounds, I usually take one of two paths. I either create a rect that fills the entire screen, like so

local bg = display.newRect( display.contentCenterX, display.contentCenterY, display.actualContentWidth, display.actualContentHeight )

Then I add some visual effect to it, like gradient or repeating texture fill, etc.

Another method that I use is to simply create a background out of tiles (or other series of display objects) and ensure that the tiles extend past any possible display resolution, this means taking the actualContentWidth and/or Height into account.

Thanks for the reply Xedur.

What should i do if i want to use a background image, how should i manage the scaling issue on these extreme devices.

Should i have two background images with different resolution.

For example

if aspectRatio == “normal” then

   background = display.newImageRect(group, “background360x570.png”, 360, 570, centerX, centerY)

esleif aspectRatio == “extreme” then

   background = display.newImageRect(group, “background360x640.png”, 360, 640, centerX, centerY)

end

or should i tweak something in config

It can’t be long before someone releases a phone with a screen shaped like a ruler or banana. Perhaps a notch that bends time and space and displays data from several frames ago, from a parallel universe.

By then, we’ll hopefully have some fancy APIs that work with them. :smiley:

As for those extreme cases, you could have two devices with resolutions such as 320x480 and 480x800. If you want to create a single background image that fits both of them, then you will have to make some sacrifices.

First of all, in order to benefit from the dynamic scaling, you need to include those @2x, @4x, etc. images in your project. Now, if you created a centered 320x480 image and your default resolution set in your config.lua would also be 320x480, then you’d most likely end up with black bars to the left and right of your image, but everything would be visible on the y-axis. You could change that the image’s width to display.actualContentWidth and height to display.actualContentWidth*1.5 and then you wouldn’t have those black bars to the sides, but the image would bleed out from top and bottom of the screen. In either case, you’d run into problems with different resolutions.

The fact is that in order to take all possible resolutions into account, you have to make some design choices. Most commonly, I keep all of my gameplay elements within my safe default area and I extend all sorts of “non-essential” display objects beyond that to fit the rest of the screen on all possible devices.

I’m aware of the concept of @2X and @4X, but i hav’nt come across any article which shows how to design for both devices without sacrificing image quality.

It’s not much of a problem when we use in-engine gradient or visual effects to render the background. But when background images are involved, i just bang my head.

I think I’ve got an idea, ill try it out and see if the outcome is good enough. It’s tough decision to not design for devices with extreme resolution as i see more and more of these getting released.

If anyone can point out to an article, it would be very helpful.

Thanks again Xedur.

I would recommend reading this before getting into much of an in-depth discussion about how to set your config.lua:

https://coronalabs.com/blog/2018/08/08/understanding-content-scaling-in-corona/

Now to the original question. There is a lot of good things to learn from Corona Cannon. It’s a pretty solid template. However, that config.lua was developed for a purpose of making sure that the top, left corner of the device was 0, 0 and the bottom, right was display.contentHeight, display.contentWidth. 

This makes edge positioning easier. People really didn’t want to write complex positioning equations using the longer display.actualContentWidth and display.screenOriginX (and the Height, Y companions). Lets face it, if you want to put a button at the bottom right of the screen:

local button = display.newCircle( display.contentWidth - 25, display.contentHeight - 25, 25 )

is a heck of a lot easier to write than:

local button = display.newCircle( display.actualContentWidth - 25 + display.screenOriginX, display.actualContentHeight - 25 + display.screenOriginY, 25 )

But in doing this, you actually make designing your game a lot harder on yourself. Edge positioned items are generally done once. You’re only going to position that button, high score, # of lives left, etc. once. You’re only going to have a small number of items to position around the edges. As we like to say in our house “Pick your battles”. Is it worth it to make positioning 5-6 objects around the edges easier if it means more work to position the rest of the game elements? In many cases, the answer to that question is a resounding “No”.

For card games where you will spread your card stacks out over the full width of the screen or games like Pop-a-Lock where pretty much everything is centered, then a computed config.lua can save you some time. But for other games, like Angry Birds, you’re probably going to create more problems than you are solving.

Lets take a deeper look into Angry Birds (i.e. Corona Cannon in this case). An iPhone X is really wide (since it’s a landscape game) and a narrow height. But you might want to play the same game on an iPad which is a fairly square device. If you position your slingshot 700 points away from the pig’s tower on the phone but on the iPad, they are only 400 pixels apart then the game will play differently on the different devices.

In this case a fixed config.lua with a centered content area where you build the game within your defined width and height will make building a game that plays the same across devices easier. It makes positioning gameplay elements easier. You know 0, 0 will be on screen. You know any objects placed at display.contentWidth/Height will be on screen. 

To build game like Angry Birds with a computed config.lua you end up having to do this:

local slingShot = display.newImageRect(...) slingShot.x = display.contentCenterX - 300 local pigTower = display.newGroup() pigTower.x = display.contentCenterX + 300

when dealing with all of your game elements is a lot more work than:

local slingShot = display.newImageRect(...) slingShot.x = 100 local pigTower = display.newGroup() pigTower.x = 700

Now you still have to build a background that fits the full width and height of the screen which means using edge calculations but when dealing with dozens of game elements vs. a few UI elements, a fixed config.lua saves you more work in more conditions than a computed config.lua does.

You have to think about your game and what’s best for you. I’m currently working on a side-scrolling space shooter and I have chosen to go with a fixed config.lua for it because I need the player’s ship to be the same distance away from the enemies.

Rob

Woah, thanks for the in-depth explanation of pros and cons about scaling and config.lua, i did check out your article before posting this topic, it helped me understand scaling perfectly, as it didn’t thoroughly cover on how to deal with an app suitable for both normal aspect ratio devices and newer extreme aspect ratio devices, i felt the need to ask around

Since you mentioned that you are working on a side-scrolling app. I’m curious whether you are using an image for a background or in-engine rendering. If you are using images for background, how do you plan on making it work on both iPhoneX and iPhone5 screens.

I apologize if i seem to be pestering you, but i want to know how each of you are dealing with newer screens as well as making it look good enough in the older ones.

One of the ways i think of is using a 360*695 (iphoneX) resolution image or multiples of it.

Problem is there will be a large portion(hidden) of image will bleed out, which will be unused in Iphone5.

Other is to have two images according to the aspectRatio of these devices and use it dynamically.

Which way seems to be the better one. Please reply

Thank you

Are you planning on creating an app with a static view or will you have some camera control where the background moves around? The answers really change a lot depending on your goals.

I personally prefer the route of least amount of work paired with most universal solution. This means that designing my apps with bleed in mind is essential. You seem to have misunderstood me earlier, as my solutions work on all aspect ratios and resolutions.

Creating full screen sized background images that fit every aspect ratio on iOS is a lot of hard work. Trying to do the same for Android is an infeasible task. Now, whether you create one image or multiple versions of an image for different aspect ratios, you’ll run into the bleed issue in either case. It’s just a matter of where the bleed is applied.

For example, if you were to create two images: 960x640px for iPhone 4S and 1136x640px for iPhone 5. If those images are used as the background and they are centered on the screen, then they cover the entire screen on their respective devices. However, when you create that 1136x640px image in your image editor, you have to fill those extra regions on the sides with something that doesn’t exist on the smaller image. Or, in other words, this would be the bleed area. If you just ignored the 960x640px image and only created the larger image to begin with, then Corona would handle that bleed instead of you in Photoshop.

Ultimately, there are as many solutions managing different aspect ratios and resolutions across devices as there are developers, so I’ll just mention a few.

If you have just a single static background, then one approach would just be to create a large image that fits within every possible display resolution that you target, but this might be a lot of work and you’d do so knowing that some parts of the image would bleed out on every device. This means that you’d have to create your image with the safe area in mind, i.e. the area that wont bleed out. You’d want to place all of your gameplay elements within the safe area to ensure that they will be visible regardless of the device.

Alternatively, you could also create the background out of multiple images. This becomes almost necessary if you want a non-static background. Take a look at these two images from Jetpack Joyride (Image 1 & Image 2). Image 1 is a screenshot of the game on a phone and image 2 is on a tablet. The background is simply a series of images placed after one another on the x-axis. All of those images are created tall enough so that they accommodate tablets. On more narrow phone devices, those top and bottom areas simply bleed out. Knowing this, the developers didn’t place any gameplay related stuff there and it doesn’t matter that it gets cut off. The UI, i.e. the distance and coin counters and the pause button are simply attached to the top left and top right corners of the screen, so they are resolution independent.

Creating backgrounds like this means that some parts of your images/background will be cut out, but it will be the non-essential parts. If you opened the game on iPhone X, then you’d simply see additional images (tiles) on the x-axis. I also included iPhone 4s and iPhone X screenshots of one endless level select module that I’ve created. It is still using the prototype images, but you’ll get the point. In this case, I’ve locked the ground to the bottom of the screen and the clouds to the top of the screen. If I were to run this on a tablet, then the only thing that would get extended is the sky itself, so in this particular case, nothing would technically bleed out. This design is also future proof, unless we get those banana screens that Nick was talking about :stuck_out_tongue:

I hope this wall of text helped you out.

Bravo, xedur. That was a clear explanation, man this is what i wanted to know. I was totally confused and afraid that i might be doing something wrong. Especially with these devices with extreme screens popping all over the place. I hope these bannana screens doesn’t get developed.

A big thanks to all of you prominent members of corona community. I have gone through the forum and found you guys seem to have exceptional and clear replies. Especially Rob.

Thanks again Xedur, for posting couple of images from the jet pack game, and explaining the design.

I agree with @XeduR, people don’t understand bleed very well. You make your background big enough to fit all the screens you want to support. Used to 16:9 screens were the tallest/narrowest form factors while 4:3 was the most square format.  I’m stuck in the old 320x480 content area. To make a background fit both 16:9 and 4:3, you need a 360x570 (portrait, or 570x360 landscape) screen. With the Samsung Galaxy S8/9 at 2:1 and the iPhone X family at 19.5:9 being the current extremes, that formula becomes backgrounds that are 360x694 (portrait or 694x360 landscape). If your background is that big, it will fit on all screens. If you use something other than 320x480 for the content area, you, of course, would need to recalculate these:

Assuming portrait:

imageHeight = 19.5 / 9 * contentWidth

imageWidth = contentHeight / (4 / 3)

Now how do you make a bleedable background? Consider this:

It might be tempting to build all those UI elements into the background like this:

But in the game, this is actually made up of 7 images:

  1. the gradient which is full screen using the above formula

  2. the gray silhouette skyscrapers. There are two-three versions that are wider than the widest screen and I stack them end to end and use an enterFrame listener to move them.

  3. the foreground buildings. Like the more distance buildings, there are multiple of them wider than the widest screen.

4-7: These are the UI elements that I draw my lives, health, score and other UI elements. They get positioned on top of everything else using edge positioning techniques so that on a widescreen the health and score are further apart. On an iPad they will be closer to each other, but maintain the same distance from the left and right edges.

This lets you constuct the total UI and make the different screen sizes work.

I totally understood now rob, thanks for giving a clear steps on how to do it. I’m trying to create a demo project on how these things work. Maybe i will post the link once its done. And one more thing that you mentioned in the article, which is to use the display.safe* API’s.

I’ll try to incorporate those and see how it works on positioning the UI Elements on different devices.

Thanks a lot for giving a clear picture on how i should be going with the design.

I went ahead and created the demo project. Its on github.

         https://github.com/MrQile/CoronaScalingDemo.git

Can anyone take a look and see if i have done it right.

Thanks

You seem to have it!

Rob

Thanks for going through it.

From what I remember, it is a great sample app and clearly demonstrates how you could create an angry birds style game. There are several other ways that I can come up with off the top of my head for creating such a game, so it really comes down to your personal preference or style. Still, that being said, it isn’t a complete game and there are some things that should be addressed if you plan on creating a commercial game like that, but it is a great sample app.

Dynamic content scaling is something that you definitely should use and it makes your life a lot easier. The thing to remember is to design your game accordingly. You should probably read https://docs.coronalabs.com/guide/basics/configSettings/index.html.

I tend to use 960x640 as my default resolution as that area is generally visible for most modern devices. Then, for backgrounds, I usually take one of two paths. I either create a rect that fills the entire screen, like so

local bg = display.newRect( display.contentCenterX, display.contentCenterY, display.actualContentWidth, display.actualContentHeight )

Then I add some visual effect to it, like gradient or repeating texture fill, etc.

Another method that I use is to simply create a background out of tiles (or other series of display objects) and ensure that the tiles extend past any possible display resolution, this means taking the actualContentWidth and/or Height into account.

Thanks for the reply Xedur.

What should i do if i want to use a background image, how should i manage the scaling issue on these extreme devices.

Should i have two background images with different resolution.

For example

if aspectRatio == “normal” then

   background = display.newImageRect(group, “background360x570.png”, 360, 570, centerX, centerY)

esleif aspectRatio == “extreme” then

   background = display.newImageRect(group, “background360x640.png”, 360, 640, centerX, centerY)

end

or should i tweak something in config

It can’t be long before someone releases a phone with a screen shaped like a ruler or banana. Perhaps a notch that bends time and space and displays data from several frames ago, from a parallel universe.

By then, we’ll hopefully have some fancy APIs that work with them. :smiley:

As for those extreme cases, you could have two devices with resolutions such as 320x480 and 480x800. If you want to create a single background image that fits both of them, then you will have to make some sacrifices.

First of all, in order to benefit from the dynamic scaling, you need to include those @2x, @4x, etc. images in your project. Now, if you created a centered 320x480 image and your default resolution set in your config.lua would also be 320x480, then you’d most likely end up with black bars to the left and right of your image, but everything would be visible on the y-axis. You could change that the image’s width to display.actualContentWidth and height to display.actualContentWidth*1.5 and then you wouldn’t have those black bars to the sides, but the image would bleed out from top and bottom of the screen. In either case, you’d run into problems with different resolutions.

The fact is that in order to take all possible resolutions into account, you have to make some design choices. Most commonly, I keep all of my gameplay elements within my safe default area and I extend all sorts of “non-essential” display objects beyond that to fit the rest of the screen on all possible devices.

I’m aware of the concept of @2X and @4X, but i hav’nt come across any article which shows how to design for both devices without sacrificing image quality.

It’s not much of a problem when we use in-engine gradient or visual effects to render the background. But when background images are involved, i just bang my head.

I think I’ve got an idea, ill try it out and see if the outcome is good enough. It’s tough decision to not design for devices with extreme resolution as i see more and more of these getting released.

If anyone can point out to an article, it would be very helpful.

Thanks again Xedur.

I would recommend reading this before getting into much of an in-depth discussion about how to set your config.lua:

https://coronalabs.com/blog/2018/08/08/understanding-content-scaling-in-corona/

Now to the original question. There is a lot of good things to learn from Corona Cannon. It’s a pretty solid template. However, that config.lua was developed for a purpose of making sure that the top, left corner of the device was 0, 0 and the bottom, right was display.contentHeight, display.contentWidth. 

This makes edge positioning easier. People really didn’t want to write complex positioning equations using the longer display.actualContentWidth and display.screenOriginX (and the Height, Y companions). Lets face it, if you want to put a button at the bottom right of the screen:

local button = display.newCircle( display.contentWidth - 25, display.contentHeight - 25, 25 )

is a heck of a lot easier to write than:

local button = display.newCircle( display.actualContentWidth - 25 + display.screenOriginX, display.actualContentHeight - 25 + display.screenOriginY, 25 )

But in doing this, you actually make designing your game a lot harder on yourself. Edge positioned items are generally done once. You’re only going to position that button, high score, # of lives left, etc. once. You’re only going to have a small number of items to position around the edges. As we like to say in our house “Pick your battles”. Is it worth it to make positioning 5-6 objects around the edges easier if it means more work to position the rest of the game elements? In many cases, the answer to that question is a resounding “No”.

For card games where you will spread your card stacks out over the full width of the screen or games like Pop-a-Lock where pretty much everything is centered, then a computed config.lua can save you some time. But for other games, like Angry Birds, you’re probably going to create more problems than you are solving.

Lets take a deeper look into Angry Birds (i.e. Corona Cannon in this case). An iPhone X is really wide (since it’s a landscape game) and a narrow height. But you might want to play the same game on an iPad which is a fairly square device. If you position your slingshot 700 points away from the pig’s tower on the phone but on the iPad, they are only 400 pixels apart then the game will play differently on the different devices.

In this case a fixed config.lua with a centered content area where you build the game within your defined width and height will make building a game that plays the same across devices easier. It makes positioning gameplay elements easier. You know 0, 0 will be on screen. You know any objects placed at display.contentWidth/Height will be on screen. 

To build game like Angry Birds with a computed config.lua you end up having to do this:

local slingShot = display.newImageRect(...) slingShot.x = display.contentCenterX - 300 local pigTower = display.newGroup() pigTower.x = display.contentCenterX + 300

when dealing with all of your game elements is a lot more work than:

local slingShot = display.newImageRect(...) slingShot.x = 100 local pigTower = display.newGroup() pigTower.x = 700

Now you still have to build a background that fits the full width and height of the screen which means using edge calculations but when dealing with dozens of game elements vs. a few UI elements, a fixed config.lua saves you more work in more conditions than a computed config.lua does.

You have to think about your game and what’s best for you. I’m currently working on a side-scrolling space shooter and I have chosen to go with a fixed config.lua for it because I need the player’s ship to be the same distance away from the enemies.

Rob