iOS8 Retina #2x images not scaling like iOS7? - swift

Has the way that Xcode 6.1 (iOS 8.1) changed the way that images are handled. In my previous Sprite Kit game (Xcode 5, iOS 7) I used the following full screen image as a background:
MainBackground_IP5#2x.png // RESOLUTION: 640 x 1136, it fills screen.
Now in Xcode 6.1 I am testing the following code (See below), the image I am using is:
MainBackground_IP6#2x.png // RESOLUTION: 750 x 1334
CODE:
func setupBackdrop() {
println(__FUNCTION__)
let backdropSprite = SKSpriteNode(imageNamed: "MainBackground_IP6")
backdropSprite.anchorPoint = CGPointZero
backdropSprite.position = CGPointZero
self.addChild(backdropSprite)
}
However when I run the application both on the simulator and device I get the following.
NOTE: If I remove the #2x it fits fine, but I can,t understand whats changed, I have not seen this mentioned in any Sprite Kit notes? I even loaded my old iPhone 5 game project and all the #2x backgrounds fit perfectly in that, it must just be iOS 8.

Images should use #2x but the problem was that in the GameScene.sks I had entered the screen resolution in pixels not points (should have been 375 x 667) Also there seems to be a problem with the GameScene.sks on the template, if you add items programatically as I did they quite often don't display. The solution to this seems to be that you have to add at least one node to the GameScene.sks (I just added an empty SKNode)

Related

inferred iPhone size not adequate

I am trying to develop for the iPhone 6 and I have an issue here that has been discussed on S.O. before, but the solution that developers have offered is not working for me.
I have taken a few pictures to try to show better what is happening.
This first screenshot is just to show that I have my Launch Images loaded:
The next picture:
Shows at the left the storyboard. As you can see the image fits the screen. The size on the inspector is "inferred" and the dimensions of it I can check by looking the size inspector:
They are 320 by 564 which corresponds to the iPhone 5s.
On the simulator as you can see there is a white gap around. and the picture at the right is a screenshot from the device running the same thing.
So to recap, i want to make an app for the iPhone 6 but on the storyboard the "inferred" dimensions are those of the iPhone 5. The simulator displays an iPhone 6 but with an image that doesn't fit and the device -weirdly- displays the image correctly.
On the next picture I have changed "Inferred" to iPhone 4.7-inch:
And I have also resized the image to fit the bigger scene on the storyboard, its now 375 by 667:
So, the normal size for an iPhone 6.
As you can see, the simulator now shows the display correctly but the device (screenshot on the right) is not correct as the image is now too big for the screen (there is no white space around the "E").
I have researched this and everyone seems to say that loading the launch images makes xCode display correctly for the iPhone 6, but that's not happening here. So what else am I missing? Thanks.

CGRectGet doesn't work well

I'm working in Swift with XCode 6 and Sprite Kit and I want to have the biggest pixel in y, so i'm using this function :
CGRectGetMaxY(frame)
and I tested my code with the iPhone 6 simulator, so the value should be 1334.0 but the console shows me only 667.0 ...
What is wrong ?
It appears you're working in "point-space" and not "pixel-space". Depending on your settings, your image (I'm assuming that's where 1334 comes from) is likely at a #2x resolution.
Check your assets folder to make sure the image is defined how it should be.
Check your scale settings
UIKit (and most of iOS) runs on point-space, so try to work in these coordinates - they abstract device resolution (important now that we have #1x, #2x, and #3x devices).
Point-space:
The original iPhone was 320x480 pixels. In order to have your code be device-agnostic, when they went to Retina, the screen and all the logic stayed at a resolution of 320x480. These didn't always correspond to pixels, so the terminology changes to "points". That's why when you grab the screen size for an iPhone 4 it still reports 320x480.
Apple's Documentation on this.

Sprite Atlas and #2x images

When using texture atlas (iPhone5) do I have to include sprite images at both normal and normal#2x sizes (even though I am only targeting retina devices). I thought I could getaway with only adding the #2x versions but sadly when I run the application the sprites come out a lot bigger than they should be (nearly 4x), I only get the right size sprites displayed when I add the normal (#1x) images to the atlas as well.
EDIT:
Starting a new project file in Xcode, if you want an image to fill the whole device display (iPhone5/5S at the maximum resolution) you need to use the #2x extension (in this case there is no "background_003.png" in the Xcode project so just the #2x version is fine)
// SETUP BACKGROUND FRAME IS {320, 568} POINTS
// IMAGE "background_003#2x.png" = 640 x 1136 Pixels
SKSpriteNode *background = [SKSpriteNode spriteNodeWithImageNamed:#"background_003"];
[background setAnchorPoint:CGPointZero];
[background setPosition:CGPointZero];
[self addChild:background];
If you add the correct sized image (640 x 1136) without the #2x Xcode takes the image and scales it incorrectly by the devices 2.0 point size, resulting in an image that is twice as big as the display.
// SETUP BACKGROUND FRAME IS {320, 568} POINTS
// IMAGE "background_001.png" = 640 x 1136 Pixels
SKSpriteNode *background = [SKSpriteNode spriteNodeWithImageNamed:#"background_001"];
[background setAnchorPoint:CGPointZero];
[background setPosition:CGPointZero];
[self addChild:background];
RESULT:
After a little bit of testing this morning I have now realised that my problem was the result of adding sprite frames in an atlas without the #2x postfix and then renaming them to include the missing #2x. It would seem that when using folder.atlas Xcode creates a plist somewhere that references the files, I can't find this and it only seems to get updated when you first add your atlas to your project. After deleting and re-adding the atlas Xcode started correctly displaying the #2x images at the right scale.
The moral of this story is therefore: if you change an atlas or its contents, make a copy, delete it from your Xcode project and re-add it again. Create all your artwork at retina resolution and add the #2x postfix to all your files, you only need none retina files (without the #2x if your targeting a none retina device) Finally when referring to art assets in code don't use the #2x postfix, so even though your monster sprite art is called "Monster_0001#2x.png" you should be referring to it in code as "Monster_0001" Xcode will work out the #2x bit for you behind the scenes, also if your using PNGs (which you should be) it will even add the ".png" for you too.
// THE ART ASSET ON DISK IS CALLED: "Monster_0001#2x.png"
SKSpriteNode *spriteMonster = [SKSpriteNode spriteNodeWithImageNamed:#"Monster_0001"];
If you only support Retina devices just add files without the #2x and you'll be fine.

cocos2d iphone 5 4 inch display support

I have been looking everywhere for this but with no luck.
How do I prepare my cocos2d based game for bigger 4 inch display of the iPhone 5?
My app is working but i want to enhance it for the bigger 4 inch display.
Cocos2d uses its own suffixes for retina display images. For retina display of the iPhone 4 and 4S it is image-hd.png. Is there a suffix for iPhone 5? How do I accomplish this?
Cheers.
There is no extra file suffix for iPhone 5, after all it's only 176 pixels (88 points) wider. It's treated like a regular Retina phone, hence cocos2d will load the -hd files.
The rest is just about positioning your images depending on the device. The simplest way is to just treat the 44 points on either side as a "dead zone" where no user input can occur and where there's no guarantee the user can see game objects.
Update:
cocos2d 2.1 added the -widehd suffix. It was said that 2.1 final release will have the suffix renamed to -iphone5hd.
In light of future screen sizes I sould personally set and use a -568hd suffix because other phones beside iPhone 5 may have the same resolution. Naming the suffix after a specific iPhone model is a tad short-sighted to say the least.
Add it to AppDelegate:
[CCFileUtils setiPadRetinaDisplaySuffix:#"your suffix"];
[CCFileUtils setiPadSuffix:#"your suffix"];
[CCFileUtils setiPhoneFourInchDisplaySuffix:#"your suffix"];
[CCFileUtils setiPhoneRetinaDisplaySuffix:#"your suffix"];
Not sure why everyone is saying there isn't.
The suffix is -568h for iPhone5/iPod Touch 5th (so the 4 inch retina displays).
The total list:
-hd (iPhone 4/4S, iPod Touch 4th)
-568h (iPhone 5, iPod Touch 5th)
-ipad (iPad 1st/2nd)
-ipadhd (iPad 3rd/4th)
Add this to AppDelegate with your chosen suffix:
if((UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) && ([[UIScreen mainScreen] bounds].size.height == 568)) {
[sharedFileUtils setiPhoneRetinaDisplaySuffix: #"-your suffix"];
}
It took me awhile to figure this out, since I'm new to cocos2d. So I thought a recap might be helpful for those like me. In cocos2d 2.1, all you have to do is creating graphics for the target screen sizes and follow cocos suffix naming convention. Note that cocos's suffix convention is not the same as iOS's.
In my case, I have a background image that occupies the full screen. So, I made...
background.png at 480x320 for iPhone
background-hd.png at 960x640 for iPhone retina (3.5")
background-iphone5hd.png for iPhone5 retina (4")
And use the following code to load the image into CCSprite. Cocos will figure out which image to use for you.
CCSprite *background = [CCSprite spriteWithFile:#"background.png"];
background.position = ccp(background.textureRect.size.width/2,
background.textureRect.size.height/2);
[self addChild:background];
For an element like a character that doesn't occupy the full screen, cocos2d will pickup character-hd.png automatically in iPhone5. There is no need to create character-iphone5hd.png version.
You can read more about this in version 2.1 release note at
https://github.com/cocos2d/cocos2d-iphone/wiki/cocos2d-v2.1-release-notes
This is how i did it for cocos2d v2.1-beta4.
In CCFileUtils.h i added:
- (void)setIphone5HDSuffix:(NSString *)suffix;
In CCFileUtils.m:
- (void)setIphone5HDSuffix:(NSString *)suffix
{
[_suffixesDict setObject:suffix forKey:kCCFileUtilsiPhone5HD];
}
In AppDelegate.m:
[sharedFileUtils setIphone5HDSuffix:#"your_suffix"];
And that's enough!
Did you follow the following post, adding the default image for it, named Default-568h#2x.png with a resolution of 1136x640?
How to develop or migrate apps for iPhone 5 screen resolution?
If it does not work, I found this post on cocos2d forum, containing a lot of infos:
iPhone 5 1136 x 640 screen resolution: http://www.cocos2d-iphone.org/forum/topic/39491
Now cocos2d support iPhone wide screen also.
-wide.png for iphone 5
-widehd.png for iPhone 5 HD
I was just playing around with suffixes in Cocos2D 2.1-rc1 and was able to get it to automatically load a iPhone5 file with the "-iphone5hd" suffix, not changing anything in AppDelegate in the sharedFileUtil section of code. Hope that helps, also.

Upgrading a cocos2d iPhone game to work at iPhone4 resolution using #2x

I am trying to add art to my game for the iPhone4 resolution. The images i am using are twice the original and i have added the #2x suffix to the image names.
When i load in a sprite like this:
[CCSprite spritewithFile:#"example.png"];
where example.png is the original image and example#2x.png is the scaled up version. When running on the original iPhone it loads the low res image and when running on the iPHone4 it loads the high res image, but it doubles the size of the image. So the high res image appears the same on the iPhone4 as on the original iPhone. Each pixel on the image takes up 4 pixels on the screen.
Any idea why this might be happening? Is there something I am supposed to do to tell the app not to double the size of the art?
Are you using the latest version of cocos2d?
The entire cocos2d API was converted
to Points. Previous versions were
using Pixels.
If your using v0.99.4:
cocos2d v0.99.4 has RetinaDisplay
support, however it required you to
use two different sets of positions
depending on the device , since the
API was in Pixels. (more)
If your using >= v0.99.5-rc0
But in v0.99.5-rc0 (and newer) the only thing that you have to do is[...] (more)
Have you read the "Retina Display in cocos2d" section of the cocos2d for iPhone wiki? (It pretty much tells you all you need to know.)