I made an iPhone game a few months ago, and am now trying to port it as a universal app to both the iPad and iPhone 5 with Cocos2D. I was wondering if there was a simple-ish way to determine where an object should be placed based on the device running the game.
I could use if statements to figure out which device the game is running on, so when I get the correct sized images for the device I could have separate positions for each object, but it seems like there would be a maths formula which would allow me to use a lot less code. Obviously something like a full screen background is very simple, because it just needs to be centred with:
[background setPosition:CGPointMake(screenSize.width/2,screenSize.height/2)];
I haven't a clue how to adapt a button that would be X = 144 & Y = 330 on the old 3.5inch, 640 by 960 resolution iPhone to an iPad or iPhone 5 resolution.
I'm willing to use a more recent version of iOS if it will make my life easier, but because I'm not using any of Apple's objects I don't know if that is possible.
Maybe this isn't even possible because the button will be different sizes for the iPhone and iPad version, but I thought I would ask.
yeah, i am usually facing the same problem,
but if it is just a static objects placement
i would have relative coordinates instead of absolute for every object
and then use screen sizes to place them correctly
so you might want to use a function like:
-(CGPoint) relativeToScreen:(CGPoint) p {
return ccp(screenSize.width * p.x, screenSize.height * p.y)
}
where 0.0 <= p.x =< 1.0 and the same for p.y
and don't forget about your anchorPoint, because the node position is based on it as well
and i hope you have discovered that cocos2d already does image choosing instead of you,
you just have to set right suffixes for your images: -hd, -ipad, -ipadhd
For iphone5 resolution, I position hud buttons relative to the screen dimensions. Very similar to what you are doing for the background. So for example, a pause button I want in the top left I would position like this:
[pauseButton setPosition:CGPointMake(0.0f + 30.0f, screenSize.height - 50.0f)];
For ipad it gets really tricky. The lazy way which I have implemented is to play around with the content scale factor and zoom everything up and have "dead" borders to compensate for the ipad's screen ratio. Not the best, but at least you can re-use all the same assets for the ipad.
Related
I'm new to the whole world of coding, and actionscript 3 is my first real experience, so sorry if I don't understand your answer straight away.
I've built an iPhone app using Adobe Flash CC in AIR for iOS. All the code is either in the timeline or separate .as files (so not using documents classes).
The core concept of the game is randomly generated objects fall from the top of the screen and the user has to tap them to make them disappear before they touch the bottom.
My problem is my document size is 640 x 960. I think this fits the iPhone 4 (haven't tested that) but when I test it on my iPhone 5s I get back bars at the top and bottom. Obviously they have different screen sizes but I want the app to be able to run on many all the different size iPhones.
I have spent hours googling this and still don't understand what I'm meant to do. I've tried playing around with the stage.scaleMode settings but nothing changes. I have also added a file called default-568h#2x.png (just a green rectangle with the dimensions 640 x 1136) in the included files but this doesn't show either.
So essentially I want to know how to change my app and AS3 code to allow my app to fit all the different size iPhones?
Any help would be very much appreciated.
LAUNCH IMAGES
First, before anything else, you need to make sure you have the correct launch images included in your project.
Here is a table from Adobe's website:
Default~iphone.png | iPhone 4 (non-retina) 640 x 960 Potrait
Default#2x~iphone.png | iPhone 4, 4s 640 x 960 Potrait
Default-568h#2x~iphone.png | iPhone 5, 5c, 5s 640 x 1136 Potrait
Default-375w-667h#2x~iphone.png | iPhone 6/7/8 750 x 1334 Potrait
Default-414w-736h#3x~iphone.png | iPhone 6+/7+/8+ 1242 x 2208 Potrait
Default-Landscape-414w-736h#3x~iphone.png | iPhone 6+/7+/8+ 2208 x 1242 Landscape
Default-Landscape-812h#3x~iphone.png | iPhone X 2436 x 1125 Landscape
Default-812h#3x~iphone.png | iPhone X 1125 x 2436 Portrait
Once you have those images made (and named exactly as shown), include them in your project (They have to be in the root of your application) by doing the following:
In FlashPro
go to your publish settings
go to the AIR for iOS Settings.
Go to the "General" tab
add all those images to the "included files" list (the root)
SCALING YOUR CONTENT
OPTION 1, FILL AND CROP
If you don't mind cropping your content a little bit, you can just do this when your app starts:
stage.scaleMode = StageScaleMode.NO_BORDER
This will scale your swf so it fills the whole screen while keeping aspect ratio. It's pretty easy to figure out how much padding you need to make this method work well for the small variations in aspect ratios for the various iPhones.
However, if you want to allow orientation changes (portrait to landscape), the cropping will likely be too severe.
OPTION 2 - RESPONSIVE DESIGN
The best way to accommodate varying screen resolutions and aspect ratios though, is to make your application responsive. This involves the following code at the start of your application:
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
Now your stage bounds (stage.stageWidth & stage.stageHeight) will be the full width and height of the device*. (some devices still have a software toolbar at the bottom or the top band)
You can then position things through code.
If you want an easy way convert what you have (you don't want to use code to resize and align absolutely everything), just put all your content in a container MovieClip with an instance name of container, you could then size and position it like this:
//scale the container as big as possible while still fitting entirely in the screen:
//figure out which dimension should match the stage (widht or height)
if(container.width - stage.stageWidth >= container.height - stage.stageHeight){
container.width = stage.stageWidth;
container.scaleY = container.scaleX;
}else {
container.height = stage.stageHeight
container.scaleX = container.scaleY;
}
//center it on the screen:
container.x = (stage.stageWidth - container.width) * 0.5;
container.y = (stage.stageHeight - container.height) * 0.5;
It's also a good idea to listen for resize events, in case the screen size changes (eg you maximize/restore on desktop, or go from portrait to landscape on mobile).
You do that by listening for the resize event on the stage:
stage.addEventListener(Event.RESIZE, redrawScreen);
function redrawScreen(e:Event):void {
//resize everything as the window size has changed.
}
You the coder are in charge of providing different solutions for different screen sizes. You check the device size and then you present the content accordingly. All in all it is not that different from showing different content based on rotation. If you hope for a magical solution that would do all that for you in AIR you are out of luck cos there's none.
Messing with the stage scalemodes is not recommended (you should always use no scale on mobile) as you then give up completely the ability to compare the position of your displayobject according the the real physical device size (basically you won't know for sure if whatever you display is in the screen or completely out of it).
If you thought developing for mobile was easy (not just using AIR but using any technology) then sorry, it's not especially cos you have to handle all those sizes.
The basic principle on how to deal with it:
get the real device size.
calculate the real density/ratio.
Compare that size to the size of your app. (again scale mode to no scale)
Extract a general ratio (size of your app compared to size of device)
Use that ratio to either, scale and place your main container (a container that contain your entire app), hard: scale and place all your DisplayObject in your app.
Since the app ratio is maintained fill the blank space with whatever.
Your app is filling correctly the entire screen on any device.
I have each of those images set in an array that calls out to Firebase for the image. I was wondering if I could have a separate array to call from for different sized iPhones because the iPhone X screen size cuts some of the text off. I want to resize the images for just the iPhone X. Is there a way to see what device the user has and then if it is the iPhone X it would show array1, and if was anything else it would show array2. I have tried looking at this post however what they did is too complicated and not what I am looking for. What I am trying to do I know is very simple. I am just not sure the direct code for it. I just need to know if it's an iPhone X then switch to array1, otherwise I don't care which device it is wether it's an iPad with cellular or wifi. Just check if the device is an iPhone X otherwise just keep everything the same.
I don't think that you should know about a model of a iPhone.
You should know about a screen/view ratio (width / height).
Ratio is a main reason to decide what images you should use.
You can find screen ratio with bounds property, for example:
if (CGRectGetWidth([UIScreen mainScreen].bounds) / CGRectGetHeight([UIScreen mainScreen].bounds) <= GOOD_VALUE){
//use one
}
else
{
//use other
}
Also screen has a property scale, that will be very useful for you.
I'm new to the whole world of coding, and actionscript 3 is my first real experience, so sorry if I don't understand your answer straight away.
I've built an iPhone app using Adobe Flash CC in AIR for iOS. All the code is either in the timeline or separate .as files (so not using documents classes).
The core concept of the game is randomly generated objects fall from the top of the screen and the user has to tap them to make them disappear before they touch the bottom.
My problem is my document size is 640 x 960. I think this fits the iPhone 4 (haven't tested that) but when I test it on my iPhone 5s I get back bars at the top and bottom. Obviously they have different screen sizes but I want the app to be able to run on many all the different size iPhones.
I have spent hours googling this and still don't understand what I'm meant to do. I've tried playing around with the stage.scaleMode settings but nothing changes. I have also added a file called default-568h#2x.png (just a green rectangle with the dimensions 640 x 1136) in the included files but this doesn't show either.
So essentially I want to know how to change my app and AS3 code to allow my app to fit all the different size iPhones?
Any help would be very much appreciated.
LAUNCH IMAGES
First, before anything else, you need to make sure you have the correct launch images included in your project.
Here is a table from Adobe's website:
Default~iphone.png | iPhone 4 (non-retina) 640 x 960 Potrait
Default#2x~iphone.png | iPhone 4, 4s 640 x 960 Potrait
Default-568h#2x~iphone.png | iPhone 5, 5c, 5s 640 x 1136 Potrait
Default-375w-667h#2x~iphone.png | iPhone 6/7/8 750 x 1334 Potrait
Default-414w-736h#3x~iphone.png | iPhone 6+/7+/8+ 1242 x 2208 Potrait
Default-Landscape-414w-736h#3x~iphone.png | iPhone 6+/7+/8+ 2208 x 1242 Landscape
Default-Landscape-812h#3x~iphone.png | iPhone X 2436 x 1125 Landscape
Default-812h#3x~iphone.png | iPhone X 1125 x 2436 Portrait
Once you have those images made (and named exactly as shown), include them in your project (They have to be in the root of your application) by doing the following:
In FlashPro
go to your publish settings
go to the AIR for iOS Settings.
Go to the "General" tab
add all those images to the "included files" list (the root)
SCALING YOUR CONTENT
OPTION 1, FILL AND CROP
If you don't mind cropping your content a little bit, you can just do this when your app starts:
stage.scaleMode = StageScaleMode.NO_BORDER
This will scale your swf so it fills the whole screen while keeping aspect ratio. It's pretty easy to figure out how much padding you need to make this method work well for the small variations in aspect ratios for the various iPhones.
However, if you want to allow orientation changes (portrait to landscape), the cropping will likely be too severe.
OPTION 2 - RESPONSIVE DESIGN
The best way to accommodate varying screen resolutions and aspect ratios though, is to make your application responsive. This involves the following code at the start of your application:
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
Now your stage bounds (stage.stageWidth & stage.stageHeight) will be the full width and height of the device*. (some devices still have a software toolbar at the bottom or the top band)
You can then position things through code.
If you want an easy way convert what you have (you don't want to use code to resize and align absolutely everything), just put all your content in a container MovieClip with an instance name of container, you could then size and position it like this:
//scale the container as big as possible while still fitting entirely in the screen:
//figure out which dimension should match the stage (widht or height)
if(container.width - stage.stageWidth >= container.height - stage.stageHeight){
container.width = stage.stageWidth;
container.scaleY = container.scaleX;
}else {
container.height = stage.stageHeight
container.scaleX = container.scaleY;
}
//center it on the screen:
container.x = (stage.stageWidth - container.width) * 0.5;
container.y = (stage.stageHeight - container.height) * 0.5;
It's also a good idea to listen for resize events, in case the screen size changes (eg you maximize/restore on desktop, or go from portrait to landscape on mobile).
You do that by listening for the resize event on the stage:
stage.addEventListener(Event.RESIZE, redrawScreen);
function redrawScreen(e:Event):void {
//resize everything as the window size has changed.
}
You the coder are in charge of providing different solutions for different screen sizes. You check the device size and then you present the content accordingly. All in all it is not that different from showing different content based on rotation. If you hope for a magical solution that would do all that for you in AIR you are out of luck cos there's none.
Messing with the stage scalemodes is not recommended (you should always use no scale on mobile) as you then give up completely the ability to compare the position of your displayobject according the the real physical device size (basically you won't know for sure if whatever you display is in the screen or completely out of it).
If you thought developing for mobile was easy (not just using AIR but using any technology) then sorry, it's not especially cos you have to handle all those sizes.
The basic principle on how to deal with it:
get the real device size.
calculate the real density/ratio.
Compare that size to the size of your app. (again scale mode to no scale)
Extract a general ratio (size of your app compared to size of device)
Use that ratio to either, scale and place your main container (a container that contain your entire app), hard: scale and place all your DisplayObject in your app.
Since the app ratio is maintained fill the blank space with whatever.
Your app is filling correctly the entire screen on any device.
I'm new to the whole world of coding, and actionscript 3 is my first real experience, so sorry if I don't understand your answer straight away.
I've built an iPhone app using Adobe Flash CC in AIR for iOS. All the code is either in the timeline or separate .as files (so not using documents classes).
The core concept of the game is randomly generated objects fall from the top of the screen and the user has to tap them to make them disappear before they touch the bottom.
My problem is my document size is 640 x 960. I think this fits the iPhone 4 (haven't tested that) but when I test it on my iPhone 5s I get back bars at the top and bottom. Obviously they have different screen sizes but I want the app to be able to run on many all the different size iPhones.
I have spent hours googling this and still don't understand what I'm meant to do. I've tried playing around with the stage.scaleMode settings but nothing changes. I have also added a file called default-568h#2x.png (just a green rectangle with the dimensions 640 x 1136) in the included files but this doesn't show either.
So essentially I want to know how to change my app and AS3 code to allow my app to fit all the different size iPhones?
Any help would be very much appreciated.
LAUNCH IMAGES
First, before anything else, you need to make sure you have the correct launch images included in your project.
Here is a table from Adobe's website:
Default~iphone.png | iPhone 4 (non-retina) 640 x 960 Potrait
Default#2x~iphone.png | iPhone 4, 4s 640 x 960 Potrait
Default-568h#2x~iphone.png | iPhone 5, 5c, 5s 640 x 1136 Potrait
Default-375w-667h#2x~iphone.png | iPhone 6/7/8 750 x 1334 Potrait
Default-414w-736h#3x~iphone.png | iPhone 6+/7+/8+ 1242 x 2208 Potrait
Default-Landscape-414w-736h#3x~iphone.png | iPhone 6+/7+/8+ 2208 x 1242 Landscape
Default-Landscape-812h#3x~iphone.png | iPhone X 2436 x 1125 Landscape
Default-812h#3x~iphone.png | iPhone X 1125 x 2436 Portrait
Once you have those images made (and named exactly as shown), include them in your project (They have to be in the root of your application) by doing the following:
In FlashPro
go to your publish settings
go to the AIR for iOS Settings.
Go to the "General" tab
add all those images to the "included files" list (the root)
SCALING YOUR CONTENT
OPTION 1, FILL AND CROP
If you don't mind cropping your content a little bit, you can just do this when your app starts:
stage.scaleMode = StageScaleMode.NO_BORDER
This will scale your swf so it fills the whole screen while keeping aspect ratio. It's pretty easy to figure out how much padding you need to make this method work well for the small variations in aspect ratios for the various iPhones.
However, if you want to allow orientation changes (portrait to landscape), the cropping will likely be too severe.
OPTION 2 - RESPONSIVE DESIGN
The best way to accommodate varying screen resolutions and aspect ratios though, is to make your application responsive. This involves the following code at the start of your application:
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
Now your stage bounds (stage.stageWidth & stage.stageHeight) will be the full width and height of the device*. (some devices still have a software toolbar at the bottom or the top band)
You can then position things through code.
If you want an easy way convert what you have (you don't want to use code to resize and align absolutely everything), just put all your content in a container MovieClip with an instance name of container, you could then size and position it like this:
//scale the container as big as possible while still fitting entirely in the screen:
//figure out which dimension should match the stage (widht or height)
if(container.width - stage.stageWidth >= container.height - stage.stageHeight){
container.width = stage.stageWidth;
container.scaleY = container.scaleX;
}else {
container.height = stage.stageHeight
container.scaleX = container.scaleY;
}
//center it on the screen:
container.x = (stage.stageWidth - container.width) * 0.5;
container.y = (stage.stageHeight - container.height) * 0.5;
It's also a good idea to listen for resize events, in case the screen size changes (eg you maximize/restore on desktop, or go from portrait to landscape on mobile).
You do that by listening for the resize event on the stage:
stage.addEventListener(Event.RESIZE, redrawScreen);
function redrawScreen(e:Event):void {
//resize everything as the window size has changed.
}
You the coder are in charge of providing different solutions for different screen sizes. You check the device size and then you present the content accordingly. All in all it is not that different from showing different content based on rotation. If you hope for a magical solution that would do all that for you in AIR you are out of luck cos there's none.
Messing with the stage scalemodes is not recommended (you should always use no scale on mobile) as you then give up completely the ability to compare the position of your displayobject according the the real physical device size (basically you won't know for sure if whatever you display is in the screen or completely out of it).
If you thought developing for mobile was easy (not just using AIR but using any technology) then sorry, it's not especially cos you have to handle all those sizes.
The basic principle on how to deal with it:
get the real device size.
calculate the real density/ratio.
Compare that size to the size of your app. (again scale mode to no scale)
Extract a general ratio (size of your app compared to size of device)
Use that ratio to either, scale and place your main container (a container that contain your entire app), hard: scale and place all your DisplayObject in your app.
Since the app ratio is maintained fill the blank space with whatever.
Your app is filling correctly the entire screen on any device.
I am making my first iphone game using corona sdk and would like it to run on as many devices as possible (phones + tablets). However I am not sure how to deal with different screen sizes and resolutions. I developed my game for the iPhone 5 using corona simulator and it works fine on that device. When I tried it on lower resolution devices like the iPhone 4 I get 2 black rectangles on each side. I tried creating 2 different backgrounds with different resolutions and added this in my config.lua:
imageSuffix = {
["#2x"] = 2
}
However this does not seem to change anything... I am not sure what height and width I should set in content in the config.lua file and what heights and widths I should set for the backgrounds. I am sorry if these questions are stupid, I am just starting.
Thanks in advance!
It sounds like you need to fully read up on config files and dynamic scaling.
The question is a little to broad as such I suggest you read this article about "the ultimate config/modernizing the config".
Some screens are wider while others are more narrow. If we take
resolution out of the equation, its easier to visualize the screens.
Corona makes it easy to take resolution out of the picture using
Dynamic Scaling. With Dynamic Scaling, you can use a common set of
screen coordinates and Corona will automatically scale the text and
graphics for different resolution screens. It can scale upwards or
downwards depending on your starting point. It also can substitute
higher resolution images when it needs to scale up. This is all
managed by a Lua file in your project folder called config.lua.
Since available resolutions vary considerably, it’s helpful to use the
same scale for each device. It doesn’t matter if you’re on an iPhone
3GS at 320×480 or a Retina iPad at 1536×2048, the location (0,0)
represents the top-left corner and (320,480), in vertical portrait
mode, is the bottom-right corner. The screen center is (160,240).
Each point, in this case, is one pixel on a lower-resolution device
like the 3GS, which has a native screen resolution of 320×480, while
each point is four pixels on a Retina iPad. Don’t worry about the math
— Corona will handle it for you.
Source: http://coronalabs.com/blog/2012/12/04/the-ultimate-config-lua-file/
This goes through the creation of a config file that fully utilize the dynamic scaling and image scaling.
local aspectRatio = display.pixelHeight / display.pixelWidth
application = {
content = {
width = aspectRatio > 1.5 and 320 or math.ceil( 480 / aspectRatio ),
height = aspectRatio < 1.5 and 480 or math.ceil( 320 * aspectRatio ),
scale = "letterBox",
fps = 30,
imageSuffix = {
["#2"] = 1.8,
["#4"] = 3.6,
},
},
}