iOS 7 and 8 makes canvas blurry on iphone 5 and 6 - ios

I've been searching for this issue with no results, so I ask this question.
I created a game in HTML5, 650x510 pixels resolution. The game scales to fit in all devices resolution, this is my scaling function:
function onResize() {
var w = window.innerWidth;
var h = window.innerHeight;
var ow = 650;
var oh = 510;
// keep aspect ratio
scale = Math.min(w / ow, h / oh);
stage.scaleX = scale;
stage.scaleY = scale;
// adjust canvas size
stage.canvas.width = ow * scale;
stage.canvas.height = oh * scale;
stage.update();
}
On all devices the game scales perfectly but on iPhone5(iOS 7.1), iPhone6(iOS 8.1) and iPhone6 Plus(iOS 8.4) when I rotate to landscape the canvas looks really blurry.
The thing is that with iOS 9.0, the canvas looks perfect on iPhone6 and iPhone6 Plus.
I've done this tests with the Xcode simulator.
Does anyone have any clues about why this blur can be happening and how to solve it?
Thanks a lot,
Mikeldi

Related

Spritekit scaling for universal app

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

SpriteKit how to get correct screen size

I've tried
self.frame.size
self.view!.frame.size
UIScreen.mainScreen().bounds.size
None of them work.
How do I get the correct screen size for the device?
You can use following swift code to get the screen size.
let displaySize: CGRect = UIScreen.mainScreen().bounds
let displayWidth = displaySize.width
let displayHeight = displaySize.height
You can use:
let deviceWidth = UIScreen.mainScreen().bounds.width
let deviceHeight = UIScreen.mainScreen().bounds.height
And if you need to get the ratio so you can detect what device they are using, you can use the following for portrait mode or switch it for landscape mode.
let maxAspectRatio: CGFloat = deviceHeight / deviceWidth
You can then check what ratio the device is to determine certain things.
if maxAspectRatio == (4 / 3) {
//The ratio of an iphone 4S is 4:3
print("The user is using an iPhone 4S or iPod 4th Generation.")
} else if maxAspectRatio >= 1.7 && maxAspectRatio <= 1.8 {
//The ratio of these devices is 16:9
print("The user is using an iPhone 5, 5S, 5C, 6, 6S, 6 Plus, 6S Plus, or iPod 5th Generation.)
} else {
print("The user is using an iPad, iPad Mini, iPad Air, iPad Retina, or iPad Pro.")
}
If you want to get the correct view that the player can see, as in the bounding frame of the device's size, you can use the following guide.

AIR iOS scaling entire content, can't see anything

I've created an app with the latest version of AIR (16.0.0.272) and I'm trying to scale the content to fit any resolution of the iPhone from 4 to 6+
In desktop debugging I see all perfectly scaled changing the stage dimension to test my solution. Trying on my iPhone 5 I can't see the scaled content.
If I comment the resize function everything is ok (I see all the content, not scaled obviously).
That's my solution
private function resize(e:Event=null):void{
w=stageW();
h=stageH();
var initW:Number=640;
var initH:Number=960;
//bg.img.width=w;
trace(w+"/"+h);
main.y=62;
//main.x=w*.5-320;
bg.width=w;
bg.height=h;
menu.bg.width=w;
menu.bg.height=h;
var divisor:Number = 640/w;
main.width = Math.floor(main.width / divisor);
main.height = Math.floor(main.height / divisor);
}
I have tried to temporize the resize call to test it on the iPhone but again after 2000ms I can't see anything.
After this I've tried with a listener addEventListener(Event.ADDED_TO_STAGE, init); calling the resize above at the end of my operations of building UI and so on.
Can't figure why resizing a movieclip that contains my app content make it disappear from iPhone and not from the desktop.
Hope in a solution
Thanks in advance
Capabilities.screenResolutionX and Capabilities.screenResolutionY are what you should use for screen width and height on apps.
Note: the X and Y don't change with rotation - they'll stay the same when screen rotates, so your code to get screen dimensions will look like this:
if (bStagePortrait) {
iScreenWidth = Capabilities.screenResolutionX;
iScreenHeight = Capabilities.screenResolutionY;
} else {
iScreenWidth = Capabilities.screenResolutionY;
iScreenHeight = Capabilities.screenResolutionX;
}
Also use this code to prevent app from resizing or moving:
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
For a variety of reasons, your resize function could be getting called more than once.
main.width = Math.floor(main.width / divisor);
main.height = Math.floor(main.height / divisor);
will continuously make the main clip smaller. It may be better to use a constant or number for size calculation. I usually do something with scaling, though.
main.scaleX = main.scaleY = percentStageScaled;

how to dynamically scale a screen in coronasdk

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,
},
},
}

CCTexture2D created texture.size not equal that image.size (only on iPad --> iPad simulator works fine)

I have very weird problem. When I run this code
CCTexture2DMutable * texture = [[CCTexture2DMutable alloc] initWithCGImage:image.CGImage resolutionType: kCCResolutioniPadRetinaDisplay];
CGFloat heightOfImage = image.size.height;
CGFloat heightOfTexture = texture.contentSize.height;
initWithCGImage is mathod that was inherit from CCTexture2D.
image <-- UIImage
I get very weird result:
On iPad simululator (works fine):
heightOfImage = 1024
heightOfTexture = 1024
On iPad (retina) (not equal???):
heightOfImage = 1024
heightOfTexture = 512
Does any one know why? It drives me crazy.
If I change kCCResolutioniPadRetinaDisplay to kCCResolutioniPad the problem is the same.
Cocos use points for measurement, not pixels (anymore). That's why the image size (in pixels) is different from the texture size (in points)

Resources