my current config file is for ipad retina and it works perfectly, however when i select a device with a smaller screen the image becomes warped.
here is my current config.lua
application = {
content = {
width = 768,--aspectRatio > 1.5 and 800 or math.ceil( 1200 / aspectRatio ),
height = 1024,
scale = "none",
fps = 60,
imageSuffix = {
["#2x"] = 1.3,
}
}
}
i would like to know if there is a way to dynamically set the width or height without hardcoding these figures for each invdividual device.
I use letterbox scaling for that.
application =
{
content =
{
width = 320,
height = 480,
scale = "letterbox",
xAlign = "center",
yAlign = "center",
imageSuffix =
{
["#2"] = 1.8,
["#4"] = 3.6,
},
},
}
Then I can use display.newImageRect, provided with dimensions of image for 320,480 device resolutions. #2 and #4 image suffixes are images 2x and 4x bigger.
Here is excellent article to get you in the corona scaling features:
http://coronalabs.com/blog/2010/11/20/content-scaling-made-easy/
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/
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 = {
["#2x"] = 1.3,
},
},
}
Related
I am having trouble properly setting up my app so that it displays correctly on all devices. I want my game to look best for iPhone and I understand that setting my scene size using GameScene(size: CGSize(width: 1334, height: 750)) and use .aspectFill means that on iPads there will be less space to display things which I'm fine with. The problem is, how do I position my nodes so that they are relative to the each devices frame height and width? I use self.frame.height, self.frame.width, self.frame.midX, etc. for positioning my nodes and when I run my game, it positions things properly considering I run on my iPhone 6, but on my iPad, everything seems blown up and nodes are off the screen. I'm going crazy trying to figure this out
I solved this in my game by using scaleFactors, numbers which tell my app how much to enlarge each length, width, height etc. Then I just make my game look well for one phone, and use that phone's width and height to calculate with which factor I need to enlarge it for other devices. In this example I use the iPhone 4 as a base, but you can use any device just change the numbers according to that device.
Portrait mode:
var widthFactor = UIScreen.main.bounds.width/320.0 //I divide it by the default iPhone 4 width
var heightFactor = UIScreen.main.bounds.height/480.0
Landscape mode:
var widthFactor = UIScreen.main.bounds.width/480.0 //I divide it by the default iPhone 4 landscape width
var heightFactor = UIScreen.main.bounds.height/320.0
Then when you make a node, a coin image for example, multiply its coordinates or width/height by the scaleFactors:
let coin = SKSpriteNode(imageNamed: "coin")
coin.position = CGPoint(x: 25 * widthFactor, y: self.size.height - 70 * heightFactor)
I think what you're looking for might be in this answer: https://stackoverflow.com/a/34878528/6728196
Specifically I think this part is what you're looking for (edited to fit your example):
if UIDevice.current.userInterfaceIdiom == .pad {
// Set things only for iPad
// Example: Adjust y positions using += or -=
buttonNode.position.y += 100
labelNode.position.y -= 100
}
Basically, this just adds or subtracts a certain amount from the iPhone position if the user is using an iPad. It's not too complicated, and you can increase or decrease both x and y values of position by a certain value of percentage of the screen (self.size.width * decimalPercentage).
Another benefit of using this way is that you're just modifying the iPhone positions, so it starts by using the default values that you set. Then if on iPad, it will make changes.
If this is hard to understand let me know so I can clear up the explanation
First of all, my app is written using mostly in Xamarin Forms, but uses a CustomRenderer for the camera. Not sure if that will affect anything.
My problem currently is that I need to change the aspect ratio of the camera from 16:9 to something custom, if this is even possible.
I have tried changing the width and height independently, but, for example, if I were to change the height to something significantly higher, all it does is expand the width and height at the same rate until it 'hits the side of the box' that the camera is contained in, so it results in the width being correct, but the height I specified in code is a lot higher than the actual height of the camera.
var videoPreviewLayer = new AVCaptureVideoPreviewLayer(captureSession)
{
// 16 / 9 = 1.77777778
Frame = new CGRect(-15, -45, size, size * 1.77777778) /*LiveCameraStream.Bounds*/,
BackgroundColor = new CGColor(0, 255, 0) //Green
};
viewLayer.AddSublayer(videoPreviewLayer);
viewLayer.Bounds = new CGRect(4, -50, 100, 50);
viewLayer.BackgroundColor = new CGColor(255, 0, 0); //Red
//Background colours included just for dev purposes to distinguish between layers
Whenever I set the height to be width * 1.777... it results in a perfect 16:9 aspect ratio, which unfortunately is not what I need. The image below shows how it is currently looking, with ideally the camera taking up all of the red area.
So my question, is how do I change the aspect ratio of this camera, if it is even possible?
I have a ZBarReaderView embedded in a viewController and I would like to limit the area of the scan to a square in the middle of the view. I have set the resolution of the camera to 1280x720. Assuming the device is in Portrait Mode, I calculate the normalized coordinates only using the cameraViewBounds, which is the readerView's bounds and the overlayViewFrame which is the orange box's frame, as seen in this screenshot - http://i.imgur.com/xzUDHIh.png . Here is what I have so far:
self.cameraView.session.sessionPreset = AVCaptureSessionPreset1280x720;
//Set CameraView's Frame to fit the SideController's Width
CGPoint origin = self.cameraView.frame.origin;
float cameraWidth = self.view.frame.size.width;
self.cameraView.frame = CGRectMake(origin.x, origin.y, cameraWidth, cameraWidth);
//Set CameraView's Cropped Scanning Rect
CGFloat x,y,width,height;
CGRect cameraViewBounds = self.cameraView.bounds;
CGRect overlayViewFrame = self.overlay.frame;
y = overlayViewFrame.origin.y / cameraViewBounds.size.height;
x = overlayViewFrame.origin.x / cameraViewBounds.size.width;
height = overlayViewFrame.size.height / cameraViewBounds.size.height;
width = overlayViewFrame.size.width / cameraViewBounds.size.width;
self.cameraView.scanCrop = CGRectMake(x, y, width, height);
NSLog(#"\n\nScan Crop:\n%#", NSStringFromCGRect(self.cameraView.scanCrop));
As you can see in the screenshot, the blue box is the scanCrop rect, what I want to be able to do is have that blue box match the orange box. Do I need to factor in the resolution of the image or the image size when calculating the normalized values for the scanCrop?
I cannot figure out what spadix is explaining in this comment on sourceforge:
"So, assuming your sample rectangle represents screen points in portrait orientation and using the default 640x480 camera resolution, your scanCrop rectangle would be {75/w, 38/320., 128/w, 244/320.}, where w=480/(320*640.) is the major dimension of the image in screen points." and here:
"assuming your coordinates refer to points in portrait orientation, using the default camera image size, located at the default location and taking into account that the camera image is rotated:
scanCrop = CGRectMake(50/426., 1-(20+250)/320., 150/426., 250/320.)"
He uses the values 426 and 320 which I am assuming have to do with the image size but in one of his comments he mentions that the resolution is 640x480. How do I factor in the image size to calculate the correct rect for scanCrop?
I found a issue that i set height and width in config .lua file as 960 * 640. When i run this app on other device which has high resolution that the above said, it got stretched. How can we set height and width in config.lua on the basis of which device it runs?
config.lua:
application = {
content = {
width = 640,
height = 960,
scale = "letterBox",
fps = 30,
imageSuffix = {
["-sd"] = 0.5,
[""] = 1,
["-hd"] = 1.4,
["-hdpi"] = 0.7
}
}
}
From now on your image.png will be displayed on every 640x960 screen. You should also include 3 additional images for other screens:
image-sd.png for screens 50% smaller than 640x960
image-hd.png for screens 140% bigger than 640x960
image-hdpi.png for screens 70% size of 640x960
Keep in mind, that you have to use only image.png in all the code. Suffix is added automatically according to what you set in config.lua
is there any possibility in corona sdk that we write one code for paticular application and it can be run on both ipad and iphone, without changing the coordinates of objects and sizes of images for both devices seperately?
Can it be possible through display.contentHeight and display.contentWidth?
Mud was basically correct. By setting the content width/height, Corona SDK will draw and scale your app on the iPhone / iPad (+retina) screens automatically. The best way to think of it is to design your app on a 320x480 screen - and then provide images for that screen size. You then create a 2nd set of images for the larger screens. By using Corona's display.newImageRect() it will load your small images for iPhone, and then the larger resolutio images on the iPad / retina displays.
Take a look at this article: http://developer.anscamobile.com/forum/2012/03/12/understanding-letterbox-scalling
Your config.lua should look like this:
application = {
content = {
width = 320,
height = 480,
scale = "letterbox",
xAlign = "center",
yAlign = "center",
imageSuffix = {
["#2x"] = 2
["#4x"] = 4
},
},
}
When you call display.contentHeight and display.contentWidth, you are simply reading those values from the config.lua file. I tend to use some global variables if I need to do any specific positioning calculations. Define these in your main.lua:
screenWidth = display.contentWidth - (display.screenOriginX*2)
screenHeight = display.contentHeight - (display.screenOriginY*2)
screenTop = display.screenOriginY
screenRight = display.contentWidth - display.screenOriginX
screenBottom = display.contentHeight - display.screenOriginY
screenLeft = display.screenOriginX
screenCenterX = display.contentWidth/2
screenCenterY = display.contentHeight/2
For example:
companyLogo = display.newImageRect("companyLogo.png",64,64)
You will need 1 64x64px image named companyLogo.png. This will be for < iPhone 4. You then need a 128x128px image named companyLogo#2x.png. Corona will use this automatically on the iPhone 4 and iPad. Again, another image that's 256x56 named companyLogo#4x.png will be used on the iPad 3 retina display.
Yes, it's possible. For example, if your app is written for 640x480, you can have it automatically scale to other resolutions by telling it how you want it scaled in your config.lua file:
application =
{
content =
{
width = 640,
height = 480,
scale = "letterbox"
},
}
More info.