Cocos2D Tutorial for iOS: How To Create A Mole Whacking Game: Part 1/2

A Cocos2D tutorial on how to create a fun mole whacking game, that is a universal app for the iPhone and iPad. By Ray Wenderlich.

Leave a rating/review
Save for later
Share
You are currently viewing page 2 of 4 of this article. Click here to view the first page.

iPad, iPhone, and Aspect Ratio

OK so dealing with the retina display is pretty easy, but what about the iPad?

Well, it turns out that there is a very annoying thing about making a game that works on both the iPhone and the iPad – the aspect ratio between the devices is different!

The iPhone is 480×320 or 960×640 – a 1.5 aspect ratio. However, the iPad is 768×1024 – a 1.33 aspect ratio.

This means that if you have an image that fills up the entire background of the iPad (768×1024) and want to re-use it for the iPhone too, it’s not going to fit exactly. Say you scale it down so it fits the width of the iPhone (multiply by 0.9375): you’ll get 720×960, so there will be extra stuff to the side that will get cut off!

Aspect Ratio of iPhone vs. iPad

This makes things kind of annoying, because not only do you run into problems with background images, but the aspect ratio also makes it difficult to use the same coordinates across devices.

There are several strategies for how to deal with this, here are a few I’ve seen/heard/used (feel free to chime in with any of your own solutions in the comments):

  • Have a “playable area” in the middle of the screen that is the size of the iPhone retina display (640×960). This will leave a little extra are around the edges – you can just cover that with a background and the player probably won’t even notice. This allows you to easily convert coordinates between devices and re-use art (high res used on iPad and retina, and normal res used on normal iPhone). This is what we’ll be doing in this Cocos2D tutorial.
  • You can make the iPad have a similar aspect ratio to the iPhone if you take 42 pixel gutters on each side of the iPad screen, and put the “main content” inside as 684×1024. If you make your content to fit within the 684×1024 box, you can scale down images for each device from there.
  • You could have different images for the iPhone, iPad, and Retina display (i.e. 3 sets) and different coordinates too. This allows maximum flexibility, but larger binary sizes and having to redo the positions of objects on different devices.

On and another complication – Cocos2D doesn’t currently have any helpful support for the iPad, in terms of loading images with the “-hd” extension automatically, converting coordinates, etc. That is up to you!

Planning the Art: Conclusion

OK, so based on the above discussion, here is the plan for this Cocos2D tutorial.

  • The art has been designed to be within a 960×640 “playable area”, used full-screen on retina-display iPhones, and centered in the iPad screen.
  • The art will then be scaled by Texture Packer to be 1/2 the size for normal iPhones.
  • The full sized-art will be named with the “-hd” extension, and the half size without, and Cocos2D will load the appropriate art based on whether the Retina display is enabled.
  • Backgrounds are a special case because they need to be fullscreen always. The backgrounds will be made to the 1024×768 size (iPad size) so the entire screen is filled. The same images will actually be used on the iPhone too since it’s close enough. Some of the background will be offscreen, but that doesn’t matter for this particular background.
  • The iPad version will contain code to use the “-hd” images, convert coordinates to inside the “playable area”, use the appropriate font sizes, etc.

Go ahead and download the art for this Cocos2D tutorial, made by my lovely wife. Unzip the file and take a look at how things are set up:

  • In the “foreground” folder, the foreground is 1024×768 (the size of the iPad), but it is actually split into two parts: the lower part, and the upper part. It’s split into two parts so we can place the mole in-between the lower and upper parts, to make him look like he’s going underground.
  • In the “background” folder, the background has the 1.33 aspect ratio of the iPad, but is actually half sized (512×384). This is becase the background barely shows (just through the three mole holes), so it’s not worth the cost of a large 1024×1024 texture load. Instead a small texture is loaded and scaled up.
  • In the “sprites” folder, all sprites were sized to fit nicely within the 960×640 “playable area”. Note there’s a mole, and two animations for him (the mole laughing, and the mole being hit).

Ok – enough background info – it’s time to get started!

Getting Started

Open up XCode, select “File\New Project…” from the main menu, choose “User Templates\cocos2d\cocos2d Application”, and click “Choose…”. Name the project WhackAMole, and click Save.

Next, take the “Art” folder that you downloaded earlier and copy it into your WhackAMole project directory using Finder. It should be a sibling to the build and Classes folders, as you can see below:

Directory Structure for Project

Next, make sure you have Texture Packer installed and ready to go on your machine. If you don’t have it already or know how to use it, check out this tutorial for more information.

You will now set up TexturePacker to create the sprite sheets you’ll need for this project. You’ll be doing everything by TexturePacker’s command line tools and XCode integration, so no need to use the TexturePacker GUI at all!

Right click on Resources, choose “Add\New File…”, choose Mac OS X\Other\Shell Script, and click Next. Name the file PackTextures.sh, and click Finish.

Then replace the contents of PackTextures.sh with the following:

#!/bin/sh

TP="/usr/local/bin/TexturePacker"

if [ "${ACTION}" = "clean" ]
then
    echo "cleaning..."

    rm resources/background*
    rm resources/foreground*
    rm resources/sprites*

else
    echo "building..."

    ${TP} --smart-update \
          --format cocos2d \
          --data resources/background-hd.plist \
          --sheet resources/background-hd.pvr.ccz \
          --dither-fs \
          --opt RGB565 \
          Art/background/*.png

    ${TP} --smart-update \
          --format cocos2d \
          --data resources/background.plist \
          --sheet resources/background.pvr.ccz \
          --dither-fs \
          --scale 0.5 \
          --opt RGB565 \
          Art/background/*.png

    ${TP} --smart-update \
          --format cocos2d \
          --data resources/foreground-hd.plist \
          --sheet resources/foreground-hd.pvr.ccz \
          --dither-fs-alpha \
          --opt RGBA4444 \
          Art/foreground/*.png

    ${TP} --smart-update \
          --format cocos2d \
          --data resources/foreground.plist \
          --sheet resources/foreground.pvr.ccz \
          --dither-fs-alpha \
          --scale 0.5 \
          --opt RGBA4444 \
          Art/foreground/*.png

    ${TP} --smart-update \
          --format cocos2d \
          --data resources/sprites-hd.plist \
          --sheet resources/sprites-hd.pvr.ccz \
          --dither-fs-alpha \
          --opt RGBA4444 \
          Art/sprites/*.png

    ${TP} --smart-update \
          --format cocos2d \
          --data resources/sprites.plist \
          --sheet resources/sprites.pvr.ccz \
          --dither-fs-alpha \
          --scale 0.5 \
          --opt RGBA4444 \
          Art/sprites/*.png

fi
exit 0

This script runs TexturePacker to create a sprite sheets for the background image, the foreground images, and the sprite images – an HD and regular-quality image for each.

Note that each image is saved in the pvr.ccz format since it is the most efficient in terms of memory and disk space usage. Also the pixel format and dithering options were chosen to get a good tradeoff of quality and memory usage for each set of images.

If you’re unsure what the TexturePacker options do, load up Terminal and run TexturePacker –help to get a full description of each option.

Next, you need to set up your project to run this shell script when you compile. Right click on Targets, choose “Add\New Target…”, and choose “External Target” (not Shell Script Target!), and click Next. Name the Target TexturePacker, and click Finish.

Then double click on your TexturePacker target and set up the settings as follows:

Texture Packer Target Settings

The final step is to set this target as a dependency of your app. Double click on your TextureFun target, go to the General tab,click the + button in Direct Dependencies, choose Texture Packer from the list, and click Add Target.

Project Dependencies

Compile your app, and you should see the output from Texture Packer from your build results if everything is working OK.

Texture Packer Results

Next, add the newly generated sprite sheets and property lists to your project. Right click on Resources and choose “Add\Existing Files…” and select the background, foreground, and sprite files (12 files total) from Resources and click Add, and then Add again. When you’re done your Groups & Files tree should look similar to the following:

Project with Sprite Sheets Added

If you’d like, you can double click on any of the .pvr.ccz files to load up a preview of what’s inside. This is a new (and handy) feature of Texture Packer!