Before the release of the iPhone 4, developers were in the comforting situation that all iPhones had the same screen resolution (unlike Android developers, which have to support many kinds of displays). Now, with the arrival of the iPhone 4, there are two screen resolutions that can be targeted: 480×320 and 960×640.
Fortunately, Apple did the best to make that transition as painless as possible. It’s no coincidence that the new resolution is exactly twice the old resolution — that way, old applications simply use 4 pixels on the iPhone 4 for what was one pixel on previous devices, and look just like before.
New applications, however, can profit from the higher resolution. If you create all graphics in the high resolution from the start, the additional effort is minimal — if you follow the steps I show below.
BTW, the tools I am using throughout this tutorial are part of Sparrow — but that does not mean that you cannot use them with other game engines (like Cocos2D) or pure UIKit applications. The texture atlas generator, for example, can easily be modified so that it produces a different output format.
What we want to achieve
Sparrow’s demo application was created in the way I am describing in this tutorial. Start up the demo application in the iPhone simulator to see the result. When the simulator appears, select “Hardware – Device – iPhone 4″ in the menu bar, and “Window – Scale – 100%”. (The next time you start the simulator, it will have remembered these settings.)
Depending on the selected hardware (iPhone vs. iPhone 4), different textures will be used. Don’t worry if the HD version runs slowly on your Mac; on a real iPhone 4, it will run smoothly.
Preparations
First, you have to make sure that the tools “texture scaler” and “atlas generator” work. They can be found in the “sparrow/sparrow/util” directory of the download package. Have a look at the README files of those tools to find out how to prepare them.
Creating the graphics
When the tools work, we can start creating the graphics. Create the textures only for the high resolution (960×640). If you use a texture atlas, place your graphics in one directory per atlas. All other graphics are in a separate directory.
This leads to a directory structure like the following:
textures/
atlas/
tree.png
house.png
guy.png
others/
button.png
background.png
As I said, those graphics are all targeting the high resolution. A tip: try to make the width and height of those textures even numbers. That way, the down-scaled versions we create below will have widths and heights that are whole numbers, and you avoid some aliasing issues later.
Now, do not add those graphics to the Xcode project! They are just the “raw material” for the graphics you use in your application. Save them in a directory outside of your project.
What we will do instead is the following: we will create two shell scripts that will use Sparrow’s tools to scale the graphics to the appropriate sizes and copy them to the project directory.
Script 1 – Normal Textures
First, we handle the textures that are loaded directly (they are not part of a texture atlas). Create the following script and save it into the “textures” directory from above. Let’s call it “scale_and_copy_textures.sh”:
#!/bin/bash
SCALE_TEXTURES=/sparrow_path/util/texture_scaler/scale_textures.rb
OUTPUT_PATH=/application_path/media/graphics
echo ""
echo "-> Renaming and copying high-res textures ..."
# no scale, add suffix
${SCALE_TEXTURES} -s 1 -a @2x others/*.png ${OUTPUT_PATH}/2x
echo ""
echo "-> Resizing and copying low-res textures ..."
# scale by 50%, sharpen
${SCALE_TEXTURES} -s 0.5 -r others/*.png ${OUTPUT_PATH}/1x
echo ""
echo "Done!"
Modify the two variables at the beginning so that they point to Sparrow’s texture scaler and to your game’s media directory. Before we can execute the script, we have to make it executable. Open the terminal and type:
cd path_to_textures/ chmod u+x scale_and_copy_textures.sh
Now you can execute it by calling
./scale_and_copy_textures.sh
If everything worked, this will create the following files in the output directory:
/graphics
/1x
button.png
background.png
/2x
button@2x.png
background@2x.png
The “2x”-folder contains the original graphics. The suffix “@2x” was added to the filenames. We’ll see later what that’s for. The folder “1x” contains the downsized and sharpened textures. (If you don’t want them to be sharpened, remove the “-r” flag in the script).
Script 2 – Atlas Textures
Thanks to Sparrow’s atlas generator, the process of creating the two atlases is just as simple. Create the script “create_and_copy_atlas.sh” in the same directory as the other script:
#!/bin/bash
GENERATE_ATLAS=/sparrow_path/util/atlas_generator/generate_atlas.rb
OUTPUT_PATH=/application_path/media/graphics
echo ""
echo "-> Creating High Resolution Atlas ..."
# no scale
${GENERATE_ATLAS} atlas/*.png -m 2048x2048 ${OUTPUT_PATH}/2x/atlas@2x.xml
echo ""
echo "-> Creating Standard Resolution Atlas ..."
# shrink by 50%, sharpen, and copy
${GENERATE_ATLAS} -r -s 0.5 atlas/*.png ${OUTPUT_PATH}/1x/atlas.xml
echo ""
echo "Done!"
The maximum size of the HD atlas is 2048×2048 pixels; that’s the maximum size of a single texture on iPhone 4. The smaller atlas has a maximum size of 1024×1024; that size is supported by all iPhone/iPod variants. Again, the smaller textures were scaled down to half of the size and sharpened.
Just like before, you have to make that file executable before you can start it:
cd path_to_textures/ chmod u+x create_and_copy_atlas.sh ./create_and_copy_atlas.sh
Now, the graphics directory should contain all of our textures:
/graphics
/1x
button.png
background.png
atlas.xml
atlas.png
/2x
button@2x.png
background@2x.png
atlas@2x.xml
atlas@2x.png
Preparations complete!
Phew! OK, that was quite a bit of work — but now, everything is prepared. From this moment on, when you add a new texture or change an existing one, all you have to do is to start up the corresponding scripts.
Using those Textures
Sparrow 0.9 makes it very easy to use those HD textures. You develop your game just like before, with a stage size of 480×320. All you have to do is to add the following line at the beginning of your application delegate:
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
[SPStage setSupportHighResolutions:YES];
// ...
}
Add all textures to your Xcode project (low and high resolution). Now, create SPImages and SPTextureAtlases just like before — no need to add the “@2x” suffix!
SPImage *background = [SPImage
imageWithContentsOfFile:@"background.png"];
SPTextureAtlas *atlas = [SPTextureAtlas
atlasWithContentsOfFile:@"atlas.xml"];
Behind the scenes, Sparrow will load the correct texture for you. The “width” and “height” properties of the loaded images and textures will always be the size of the low resolution (!) textures. That way, you can pretend that you are developing the game only in the low resolution. The HD-version will be a side-product you don’t have to think about while you are writing your game in Xcode.
Last words
This tutorial should have shown you nearly everything you need to know to create your next game in HD.
One thing I left out is Bitmap Fonts. Sparrow has no tool for that on its own. I recommend you use the bitmap font generator by AngelCode. To use bitmap fonts in HD, create the font files two times: once with the high resolution and the suffix “@2x”, and once with half the size (and no suffix). The demo project contains a bitmap font that shows you what the files should look like.
I think that should be it! If anything is unclear, just post your question below or in the forum — as always. Good luck!
UPDATE: What about the iPad?
You will have noticed that this post was only about the iPhone and iPod variants, not the iPad. Here’s the reason for this:
When you create an iPad-only application, there’s nothing special you have to think about. The SPView and SPStage objects will have a size of 1024×768, and you create textures for that size. That should be straight forward.
However, so-called “Universal Apps”, which contain iPad and iPhone/iPod versions within one application bundle are bit special. Currently, the “@2x”-textures are not loaded automatically on the iPad (and you’d need to modify the Sparrow source to do so).
Why is that so? Well, first of all, I expect that as soon as iOS 4 is released on the iPad, I bet that Apple will start up applications that were built for the retina display in full screen mode (well, at least in 960×640). That means that the application will run in high definition automatically.
Second, for a real iPad-app (universal or not), you normally don’t want to simply scale up everything, anyway. An iPad application should make use of the additional screen space, not just display everything twice the size. So I’m afraid you will have to use a different set of textures for the iPad, anyway (in scale, somewhere between the HD and LD textures), and move the controls and graphics to different positions. If that is not feasible: as I said above, I am confident that iOS 4 on the iPad will take care of the simple “double size” solution.
If I am mistaken about Apple’s plans — don’t worry, in that case, a Sparrow update will take care of that!


Interesting articicle, but I have a question it’s possibile to build a game for iPhone, iPhone 4 and iPad, if yes how manage the iPad textures?
Thanks
Hi Monty!
Thanks for that question! I should have mentioned the iPad right away, of course. I updated the blog entry with my views on that topic!
Daniel
The atlas script is bad. If a game has more than 1 atlas, they will be saved under the same name and overwrite each other.
Hi Kostya!
If you want to create more than one atlas, you just have to add more calls to “generate_atlas.rb” — one line per atlas and scale factor. Then, change the last parameter from “atlas.xml” to “other_atlas.xml” or whatever you want. I hope that helps!
But it doesn’t make changes in the previous XML file of atlas. It just overwrite it with the new one that has just 1 big “sprite” at the size of the scaled texture.
Its much safer to scale atlas textures in Photoshop and then to make changes in the XML using a text editor.
Sorry, Kostya, I just don’t understand what you mean. If you want, you can post a detailed description of your problem in the forum, or write me a mail.
Thank you, I was just looking for this. A very useful feature.
You’re welcome! And thanks for linking to the article =)
Thanks for mapping this out for us
I really appreciate the detail.
HI Daniel,
I try to make an universal game, that should use the HD resources for iPAD, and you might be right about the iOS4 update, but today is 1 day before release and still no info about an individual use of retina iPhone simulation on the iPad yet (also not from the ones who tested beta versions). I think Apple wants to keep the iPad different in some way (it is actually).
Since I think it might not be the biggest deal to update the sparrow code for loading the @2x resources in case of running on an iPad, could you be so kind and give a hint where in the sparrow code this might happen?
thanks in advance, and again, thanks for the detailed descriptions, excellent blog entries and support of your framework. I think if you keep up the efforts you will be in the top league of 2D frameworks for iOS.
Hi Asebit,
yes, it seems I was mistaken with my assumption. What I did not take into account was that the iPad has only half the RAM of the iPhone4. Thus, a lot of applications would presumably crash because they were never tested in the combination “HD textures, 256 MB RAM”. I guess that’s why it’s not implemented in that way.
However, iOS 4.2 will make it easier to add the HD option for the iPad. I will have a look at it as soon as the final version is out, and will report my progress in the forum! If you need support for that feature sooner, you can have a look at this forum thread.
BTW, thanks a lot for the compliments =)
Hi all!
Im having a bit of trouble using the retina display…
The script and all works, Although the sizes in the xml where not resized. I’ve done this by hand.
The problem is: when I add the @2x images to the project everything gets messed up..
See screenshots:
http://imageupper.com/g/?S010001005Z2905470441157022
Hm, if you had to manually change something in the xml, there must be something you have to do differently. Perhaps that’s the reason for the problem that emerges later! Have a look at the atlas creation process again, perhaps you’ve missed something!
Even though something might have gone wrong during scaling, I fixed them by hand afterwards. Ill double-check when I get home..
Problem solved; Be sure to call supportsHighResolution: before your initialize your stage.
I’v e got problems using the script. When I execute it it results in
sh: -c: line 0: unexpected EOF while looking for matching `”‘
sh: -c: line 1: syntax error: unexpected end of file
/Library/Ruby/Gems/1.8/gems/quick_magick-0.8.0/lib/quick_magick.rb:174:in `exec3′”
Did anyone else face this issue?
Hm, there must be a problem with your quick magick gem, perhaps a compatibility issue! Perhaps you can reinstall that gem?
If you that doesn’t help, try to post the question in our forum, that way more people will read your question.