Make Flixel (iOS port) support retina graphics - ios

In case you are familiar with the Flixel game engine, open sourced here:
https://github.com/ericjohnson/canabalt-ios/tree/master/flixel-ios
How would you go about adding support for retina graphics? Like retina sized textures.
I tried adding #2x atlas pngs and they seem to load, however I guess the offsets will be incorrect as specified in the atlas plist. Changing the plist (load retina atlases for retina devices) with correct offsets surely loads the graphics correctly, but the textures themselves generally shows up too big, and other problems seem to occur.
Progress update:
As noted above I'm creating separate texture atlases for high res graphics - I guess this would mean I would need to have a complete set of high res graphics (or none at all) to make things simple. This makes the graphics load correctly (or the offsets are incorrect of course if using lowres atlas plist)
When creating FlxSprite:s, I don't use the shorthand static creators, but the init* constructors, specifying the modelScale parameter using the device's scale (will be 2.0 for retina devices, 1.0 for other). With this the graphics also show up with correct size on screen no matter retina screen or not.
What's left is make the retina versions use the correct resolution because somewhere the texture itself seems shrunk, then sized up again producing a blurry, incorrect effect - not the original high res image. I'm guessing the last culprit is somewhere in SemiSecretTexture class...
Progress update again:
I was likely just wrong above. I think I found out how to do it. No need to set modelScale to 2.0... I might sort out the details and provide the answer later :-)

I guess there's no straight forward way to do this, but when you instantiate your class derived from FlxGame, don't use YES in the zoom parameter. For starters. Then you'll have to load different atlases for retina and non-retina. Not sure what happens with iPad support from there however. Then when loading textures for FlxSprites, you need to specify the "device scale", which would be 2.0 for retina devices - get it from [UIScreen scale]. This would make retina and non-retina work good for FlxSprite. Then FlxTileblock (and possibly other classes) is another story which I haven't solved yet.

Related

How important are non-retina images?

I'm releasing a new update for one of my apps and I was disappointed to see that it just barely surpasses 20MB estimated size (20MB is the point where it can no longer be downloaded over cell data).
My app contains a lot of images, so I could greatly reduce the size if I didn't have all those non-retina images. I know that there are some non-retina devices that will be running my app. So here are my questions:
How will a non-retina device react if I have an image with the #2x suffix but no non-retina image without it.
If I use a retina sized image without the #2x suffix and scale it down to the size I want to display it at programmatically and/or
through interface builder, will it still maintain full quality on
retina devices? Will the quality be worse on a non-retina device
than using an image I downscaled from the original using GIMP
instead?
How will a non-retina device react if I have an image with the #2x suffix but no non-retina i
image without it.
I use that approach on a couple of apps of mine and it works flawlessly. I am not able to detect any performance or visual issues on non-retina display devices (concretely, iPad 1/2 and mini).
I am not sure what can happen on older iOS version, since I only support iOS5+ on those apps.
If I use a retina sized image without the #2x suffix and scale it down to the size I want to display it at programmatically and/or through interface builder, will it still maintain full quality on retina devices? Will the quality be worse on a non-retina device than using an image I downscaled from the original using GIMP instead?
This comes down to how you set interpolation options while doing the scaling. See this other question for more details on how interpolation quality affects scaling down an image. In GIMP or Photoshop you also have control on the interpolation to be used for scaling, btw.
But in the end I don't think you need to go this way.
Most importantly, that bandwidth limit has been raised to 50MB.
OK.
If you only provide one image then you have one of two possibilities.
The image is a non-retina image. This will look fine on the non-retina. It will look identical on a retina device. But will look low quality next to a retina image.
The image is a retina image. On the retina device it will still load as a retina image. It will look fine. However, on the non-retina device it will have to scale down the image. This takes extra cycles of the CPU so could affect performance and it may not look how you want. It may shrink the image using a different method than you want and so may make the image look odd.
This is the same with or without a suffix.
The best solution is to create retina images and then use your editor of choice to create the standard versions. Nothing will stop you only providing one image but it may lead to a look and performance that you don't want.
On a side note. The size for downloading over cellular data was increased to 50MB.
Try these things using the simulator and find out for yourself.
I think the answer is that UIImage will ignore the #2x choice if you're relying on [UIImage imageNamed:#"without2xSuffix.png"] and not find anything, but I haven't tried it. Deliberately requesting the #2x file will work, but whether the image will be scaled, tiled, stretched or centered (or something else) is up to the place where it's used.
Note that the documentation says that unless you use the name without the #2x suffix and let iOS find the 2x version for you, it will set the scale of the image to 1.0 rather than 2.0, which complicates drawing. You'd have to load the image using imageWithData:scale: to fix this.

iOS: #2x - does it mean anything besides twice the size?

Silly question. But regarding images for iOS, I keep seeing the #2x identifier. Does that just mean the image is twice the size and therefore clearer as opposed to "#1x" image with the same dimensions? Or does the #2x actually mean something when compiling. What's the drawback to just using larger images and scaling them down inside xcode?
Clearly I don't understand something.
#2x is just the convention Apple chose for what image to use on a retina device vs a non-retina one—it has no meaning for compilation.
Using larger images and scaling them down doesn't look as good as using 1x images (you can try it yourself). Sometimes a designer might also e.g. remove details from a 1x image because at the lower resolution you can't make them out. Some things also don't scale down well, such as 1px lines. Scaling down images also adds overhead in I/O (opening a larger file) and at runtime (scaling algorithm).
Technically the #2x doesn't even need to be double the size of the 1x, though it's rare that you wouldn't want to do that (in one case for me, I was using resizable images and it was more convenient to have their cap-insets be exactly double even if the images themselves weren't).

iOS: Updating old application to Retina graphics (TweeJump)

I'm new to the site and also iOS developing as well, but I have experience with other developing platforms.
I have been studying and playing around with the TweeJump source code and I want to update it to Retina graphics, I have made my own but I'm not sure how to implement them properly. Does doing this cut off support for non-retina iPhones?
Some of the images are in a sprite, which I'm not familiar with.
If I just change all the images to high resolution ones, what problems will arise and how can I resolve them?
Please excuse my beginner knowledge. I will really appreciate ANY help you can offer.
Regards.
Updating your game to support Retina display is easy if you have the original non-rasterized (e.g vector) graphics for the images. Just export the graphics as twice as large as the SD images and append -hd (or -ipadhd for iPad) to the part of the filenames before the extension. Just make sure your app delegate calls [[CCDirector sharedDirector] enableRetinaDisplay:YES] and you are good to go.
Does doing this cut off support for non-retina iPhones?
Absolutely not. As long as you retain the SD images.
Some of the images are in a sprite, which I'm not familiar with.
You mean "spritesheet"? This is one of the situations where you need to have access to the original vector graphics for each individual sprite. Plus, you need to use a spritesheet editor in order to generate the HD version of the spritesheet. I recommend TexturePacker.
If I just change all the images to high resolution ones, what problems will arise and how can I resolve them?
Make sure to retain the SD versions as well. One of the problems that may arise is if you have a spritesheet with the size of larger than 1024 x 1024 for the SD version. The HD version will have size larger than 2048 x 2048 which OpenGL ES 1.1 cannot support. You would need to break the spritesheet into more pieces or convert to OpenGL ES 2.0 (i.e. convert to cocos2d-iphone 2.x).

Retina Display images looks fuzzy and blurred. No Reason why?

I am a Cocos2d game developer. I am developing a game using retina display images.
I have created texture files with and without HD suffix using zwoptex.
I have added those zwoptex plist texture files in app-delegate like [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"Background.plist"];
I have enabled the retina display to YES [director enableRetinaDisplay:YES];.
I have used the png files from the plist wherever i want using ccsprite *background = [CCSprite spriteWithSpriteFrameName:#"sample.png"];.
All those png files which I have included are high resolution images with both sizes 960*640 and 480 * 320. But in no reason the images look blurry and fuzzy when i run the game in simulator or iPhone. Anyone please help me to solve this issue …..
(The following image was posted as an example in a comment.)
cocos2d applies anti-aliasing to sprites by default. You need to turn that off:
[background.texture setAliasTexParameters];
hope this helps.
The screenshot you posted (I took the liberty of adding it to your question) shows that it was taken from the iPhone Simulator and not the iPhone (Retina) Simulator. Therefore it will not use the HD images.
With the iPhone Simulator running go to the Hardware -> Device menu and select iPhone (Retina) as the device. Then restart your app.
Note also that the iPhone Simulator will only render the game with a color depth of 16-Bit, regardless of settings in cocos2d or your Mac. The iOS Simulator renderer is limited to 16-Bit rendering for performance reasons (it only uses software rendering, no hardware acceleration). Only by looking at the game on an actual device can you make judgement calls about image quality.
To test whether the game is actually loading the HD assets or for some reason just loads the SD images, try running it without the SD images. If the game tries to load the SD images it will cause an error. If not, it is loading the HD images and the "blur issue" has a different cause. You could also log which files are loaded by adding a NSLog statement to the CCFileUtil class method fullPathFromRelativePath which performs the file name changes to load -hd images whenever possible.
You'll find that even miniscule amount of scaling or rotation applied to a sprite may have it look blurred, so check if you happen to do that. Any change in blend modes (using ccBlendFunc) could also cause blurred images. Also check that your images are fully opaque (opacity == 255).

iOS apps - why include both #2x and low-res images?

This has been bugging me for a while. I don't understand why one should include low-res images. If a 3GS, for example, can't find the low-res image, it just uses the #2x version anyway and displays it at it's native resolution. So why add to the filesize of your app by including all the half-res images?
Halley had it right. The system does not automatically downsample #2x images to non-retina size, and it shouldn't. The 3Gs does not have enough memory to load retina images. It will likely choke your app and cause it to exit with an out of memory error.
The problem gets even worse with the iPad 1. The iPad 1 has very low memory relative to it's screen size, and if you tried to make it load retina sized images, it would choke and die very quickly.
To scale an image the system has to load it at full size and do a complex scaling operation each time it draws it. It's the worst of all possible worlds - slower, 4x as much memory, and the images don't look as good.
In most cases, you can make an icon look better when created at the low-res resolution, instead of having the system scale it. If you don't care too much about how your icons look when scaled, then using the #2x version only is probably fine.
The other posters mentioned some excellent points, but here's one more for posterity: as mentioned several times in http://developer.apple.com/library/ios/#DOCUMENTATION/UserExperience/Conceptual/MobileHIG/IconsImages/IconsImages.html#//apple_ref/doc/uid/TP40006556-CH14-SW1, a 2x image may be more detailed. In other words, the low-res image isn't simply a scaled-down version of the 2x image; the 2x image may contain details not present in the smaller image.
#2x filenames are intended for Retina Display enabled devices.
If you intend to use them for display on the iPhone 3GS make sure to properly test that they look as acceptable as the low-res image Apple wants you to use.
The reason being, is when images are scaled up if there is no #2x available, they can become pixelated and blurry, so you would prob think that making the original image twice as big would solve the problem.
But no, because the retina devices would still scale it up (in my experience) and non retina devices would display the image incorrectly.
It's got a lot to do with the quality standards Apple wants for the Apps on their app store

Resources