Bonus Chapters

Chapter 25: Performance: Texture Atlases 4! Advantage 1: Use less memory ...... 5! Advantage 2: Run faster ...... 7! Using texture atlases ...... 11! Pixel formats ...... 14! Manual texture atlas generation ...... 18! Texture atlas pitfalls ...... 23! Challenge: Preloading power ...... 29! Chapter 26: Performance: Tips and Tricks 32! Getting started ...... 33! Introducing Instruments ...... 34! Touring the code ...... 36! Reducing sprites and physics bodies ...... 37! Reducing particle systems ...... 39! Other performance tips and tricks ...... 42! Challenges ...... 44! Chapter 27: Making Art for Programmers 46! Choose your path: hire or DIY? ...... 47! How to find and hire an artist ...... 48! Paying your artist ...... 49! Getting started ...... 51! Start with a sketch ...... 52! Getting the sketch into Illustrator ...... 57!

2

Tracing the sketch with vector lines ...... 61! Custom stroke widths for a more natural line ...... 64! Coloring your artwork ...... 67! A bit about shadow and light ...... 78! Exporting PNG files ...... 84! Challenges ...... 86!

3 Chapter 25: Performance: Texture Atlases

By Rod Strougo

A great game needs more than just fun and polish – it also needs to perform well. Customers expect a smooth frame rate while they play. Nothing breaks the player’s concentration like a slow frame rate, or a mid-game stutter!

One of the most important performance optimizations you can make to your game is to use texture atlases. As you may have noticed, you’ve already been using texture atlases for most of the games in this book!

Starting with Cat Nap back in Chapter 9, “Intermediate Physics,” you put your sprites inside a folder that ends with .atlas. Behind the scenes, Sprite Kit generated a texture atlas for you that looked something like this:

Although you learned that using texture atlases is a good practice, you didn’t learn why. You also didn’t learn about some neat optimizations you can make to your texture atlases – good practice on top of good practice – all of which adds up to your game using less memory and running faster. iOS Games by Tutorials Chapter 25: Performance: Texture Atlases

In this chapter, you’ll take a deeper look at texture atlases and exactly why it’s important to use them. You’ll also learn how you can save memory in your game by choosing the proper pixel format for your images, as well as how you can avoid some common pitfalls with texture atlases.

Let’s begin by making the case for texture atlases and examining their two major advantages.

Advantage 1: Use less memory The first benefit of using texture atlases is that it decreases your game’s memory usage.

Memory is a precious resource on iOS devices. The iPhone 4S has only 512MB memory versus 4GB+ on a typical . Reducing the amount of memory your app uses is important for several reasons:

• Increase performance. After flash storage, accessing memory is the second slowest part of the hardware. The more you can reduce memory requirements, the faster your app will run. • Keep your app from crashing. If your game has a lot of images and textures, it’s quite possible for your app to use more memory than iOS currently has available. iOS will try its best to terminate other apps to make up the difference, but if that fails iOS may terminate your app due to insufficient memory. To customers, this will look like a crash, so is definitely something you want to avoid. • Keep your app running in the background. When memory gets low, iOS terminates apps that are running in the background, beginning with the largest memory hogs. If you decrease your memory requirements, you decrease the chances of iOS terminating your app when it’s in the background. This makes your customers happy because your app appears to launch faster. The biggest use of memory in your games by far will be textures. Therefore, when it comes to reducing your memory load, this is the first area you should address. Determining memory costs of textures The first question to ask yourself when considering your game’s memory load is, “How much memory are my textures using?”

You might think that’s as simple as looking at the size of your images, but unfortunately that’s not the case. The GPUs on iOS devices can only handle a special format called PVRTC natively. Every other image format must be stored uncompressed for the GPU to be able to render it. As an example, a 1420x640 pixel, all-green PNG background takes up a measly 57KB on flash storage, but once loaded into memory it consumes 3640KB!

5 iOS Games by Tutorials Chapter 25: Performance: Texture Atlases

Each image has a pixel format, which specifies how many bits track each color for a pixel. How many bits you use per pixel is what determines whether your image supports 8, 16, 256, thousands or millions of colors. The more bits per pixel, the larger the number of colors that you can store in an image, and generally the better the image looks.

The iOS GPU supports millions of colors and the highest quality pixel format is called RGBA8888. This means each pixel has 32 bits – 8 bits each for the Red, Green, Blue and Alpha values. By default, Sprite Kit creates textures and texture atlases in this format, but later in this chapter you’ll learn how you can specify lower quality formats if you’re willing to sacrifice quality in return for memory savings.

The simple formula you can use to determine how much memory a particular image uses is: (Length x Width x Bits per Pixel)/8 = Bytes in RAM. For example, iOS will uncompress a 128x128 image to (128 x 128 x 32) / 8 = 65K bytes in memory. Why texture atlases help Now that you know how to calculate the memory costs of textures, let’s see why texture atlases help save memory.

Imagine you wanted to use these four 161x161 images in Cat Nap:

If you added these images to your game individually rather than in an .atlas folder, using the formula above, iOS will uncompress each image to (161 x 161 x 32) / 8 = ~101K in memory, or ~405K for all four images.

If you put these sprites in an .atlas folder instead, Sprite Kit will automatically generate a texture atlas for you. A texture atlas is just a single larger image containing all of the smaller images inside it, as well as instructions for how to extract each of the sub-images. Here is what it might look like for the cat images above:

6 iOS Games by Tutorials Chapter 25: Performance: Texture Atlases

In this example, Sprite Kit generates an image that is 277x309 pixels. Using the formula above, iOS will uncompress this to (277x 309 x 32) / 8 = ~334K in memory. This is 71K in savings!

The best part is usually the more images you pack into a texture atlas, the more memory savings you get.

Advantage 2: Run faster The second advantage of using texture atlases is that it makes your game run faster –above and beyond the performance boost you get from Advantage 1, using less memory. Sprite Kit is built on top of the OpenGL ES graphics API. To draw a texture on the screen with OpenGL, there are two steps: 1. Bind the texture. First OpenGL needs to make the texture you want to use active. This is called binding the texture, and it’s an expensive operation. 2. Draw the texture. Then OpenGL draws a portion of the texture (i.e. the portion that contains the sprite image) to a portion of the screen (i.e. where the sprite is). This is also an expensive operation. If you aren’t using texture atlases and are just using sprites directly, every time you draw a sprite you have to perform both of these steps. Here is what the bind and draw calls would look like for a game with three images:

7 iOS Games by Tutorials Chapter 25: Performance: Texture Atlases

There would be a total of six calls, three bind calls and three draw calls interleaved. Since both of these calls are expensive, once you have a non-trivial number of sprites in your game you will quickly see your game’s frame rate drop as the GPU spends more and more time binding and drawing the individual textures. Why texture atlases help Since texture atlases combine all of your sprites into a single larger image, you only need about one bind call and one draw call total for all the sprites that are part of the texture atlas. The exact amount of bind and draw calls can vary depending on your usage of texture atlases and how Sprite Kit optimizes things behind the scenes.

Here is what the bind and draw calls would look like if you were to use a texture atlas for this three-image game:

8 iOS Games by Tutorials Chapter 25: Performance: Texture Atlases

Since all of the sprites are using the same texture atlas, OpenGL only needs to bind the texture once. And there is also only one call to draw textures, since OpenGL can draw the three different sub-parts of the texture to the screen in one pass.

With fewer OpenGL calls, your game runs faster. You might not notice a big difference if you only have a small number of sprites, but the more sprites your game has, the more important this becomes. Introducing PerformanceTest To see the performance benefits for yourself, open PerformanceTest- NoTextureAtlas in the resources for this project. Build and run on an actual iOS device – it is very important to do performance testing on an actual iOS device rather than the simulator in order to get accurate results.

You should see something like the following:

9 iOS Games by Tutorials Chapter 25: Performance: Texture Atlases

This is a very simple app that displays 500 sprites to the middle of the screen. This version uses individual images for every sprite, and you can see that it is getting about 38 FPS on my iPhone 5.

Next, open PerformanceTest-RGBA8888 and get a clean start by holding down the option key, clicking Product\Clean Build Folder, and deleting the app from your device.

This is the same exact project, but it uses a texure atlas (AllElements.atlas) instead of individual sprites. Build and run on your device, and you will see an increase in FPS (from 38 FPS to 48 FPS on my iPhone 5):

As for demonstrating the memory benefits of texture atlases, you’ll see a better example of this later in this chapter.

10 iOS Games by Tutorials Chapter 25: Performance: Texture Atlases Using texture atlases It’s very simple to use texture atlases in Sprite Kit. There is no additional code you have to type – most of the work is done for you by Xcode.

As mentioned earlier, need to do is put any images you want included in a texture atlas inside a folder with an .atlas extension and add that folder to your Xcode project.

For example, here’s what happens if you were to place the two ships and asteroid into a folder named MiniElements.atlas. Xcode would automatically combine the three images into a single texture atlas behind the scenes:

There’s no additional code required to use texture atlases. When you initialize a sprite like this:

SKSpriteNode *asteroid = [SKSpriteNode spriteNodeWithImageNamed:@"asteroid-medium"];

Sprite Kit will first look for a stand-alone image file with this file name and then search the texture atlases for a match. If your image is in a texture atlas, that atlas is automatically loaded and used behind the scenes.

Note: Sprite Kit will by default look for PNG images, so the extension is not necessary. If your images are in other formats, such as JPG, you will need to add the extension to the call shown above.

If you want more control over specifically what texture atlas to load, you can use the SKTextureAtlas and SKTexture classes. Here’s an example:

11 iOS Games by Tutorials Chapter 25: Performance: Texture Atlases

SKTextureAtlas * atlas = [SKTextureAtlas atlasNamed:@"MiniElements"]; SKTexture * texture = [atlas textureNamed:@"asteroid-medium"]; SKSpriteNode * asteroid = [SKSpriteNode spriteNodeWithTexture:texture];

You can use the SKTextureAtlas class to get a reference to a specific texture atlas and the SKTexture class to get a reference to a particular texture within a texture atlas. Then you can create a SKSpriteNode from that texture to have fine-grained control over which texture atlas a sprite comes from. This is the same technique that Pest Control used earlier in this book.

Of course, going this slightly longer route is not required – it’s only for those occasions when you find you need the extra control. Maximum texture atlas size According to Apple’s Texture Atlas Help document, the maximum size of a texture atlas is 2000x2000 pixels. If you have more images than can fit in a 2000x2000 texture atlas, Xcode will create additional texture atlases until all images in the .atlas folders are inside an atlas.

Note: The actual limit on the GPU for many iOS devices is 2048x2048 pixels, so you may wonder why the Sprite Kit documentation mentions 2000x2000 pixels. Our best guess is that Apple is reserving some pixels so that they can extrude your textures (a technique to avoid image artifacts).

Here are a few rules of thumb about this:

• Make them fit. If you have more images than can fit inside a single texture atlas, you start to lose some of the performance benefits you learned about here. It’s good to put some thought into how big a texture atlas will be and structure your texture atlases to avoid going over this limit where possible. • Separate by scene and layer. As you’ll learn later in this chapter, one good way to organize your texture atlases is based on what is displayed in a single game scene (or layer within a scene) at once. • Don’t put backgrounds in texture atlases. For very large images, like full- screen backgrounds, you don’t get much benefit from using texture atlases. This is because the benefits of using texture atlases result from memory and performance savings from small images you draw many times, but these are large images you draw only once. It’s often better to leave full-screen background images as normal sprites instead of putting them inside texture atlases.

12 iOS Games by Tutorials Chapter 25: Performance: Texture Atlases

Texture atlases and retina displays With the iPhone 4, Apple introduced a new technology called retina displays. These are displays that are so crisp that the human eye is unable to detect the pixel boundaries at a typical viewing distance.

The iPhone 4’s screen is 960x640 pixels – double that of its predecessor, which is 480x320 pixels. To make it easier to deal with the different screen resolutions, instead of working with pixel units in your code, Apple has introduced the concept of points. Points are a unit of measurement where:

• On a non-retina display, 1 point equals 1 pixel. • On a retina display, 1 point equals 2 pixels. You might not have realized this, but you’ve been using points in this book all along, as that is Sprite Kit’s unit of measurement. The advantage of using points is that you don’t have to change your positioning logic or values when moving between retina and non-retina displays. You can position an image at (100,100) points and trust that it will be in the same position on both types of displays.

The second piece to this puzzle is that you need artwork that is double the size in pixels for retina displays. Sprite Kit also makes this easy. Just like in UIKit, all you need to do is add a double-sized version of each image to your project with a “@2x” suffix on the filename. For example:

• spaceship.png ! Non-Retina • [email protected] ! Retina Sprite Kit will automatically choose between the 1x and 2x versions of your image at runtime without any additional code from you. Loading an image or texture atlas will cause Sprite Kit to choose appropriately, according to the device. For example, consider the line to create a sprite:

SKSpriteNode *playerShip = [SKSpriteNode spriteNodeWithImageNamed:@"spaceship"];

If you execute this code on a retina device, Sprite Kit will load [email protected], while on non-retina device, it will load spaceship.png.

Xcode 5 will create two texture atlases if it detects you have retina and non-retina images in your .atlas folder. The retina images in your atlas folder should have a suffix of “@2x” and the same base file name as the non-retina versions.

Note: In addition to the @2x suffix, Sprite Kit also supports the ~ and ~ suffixes. These allow you to specify different versions of images specific to iPhone or iPad devices. To learn more about this, check out Apple’s Drawing and Printing Guide for iOS.

13 iOS Games by Tutorials Chapter 25: Performance: Texture Atlases Pixel formats Just as important as using texture atlases instead of individual images is choosing the correct pixel format for your texture atlases.

As you learned earlier in this chapter, by default Sprite Kit uses the highest quality pixel format: RGBA8888. This means texture atlases use 32 bits of color data for each pixel: 8 bits for each of red, green, blue and alpha (transparency). This gives you the best looking images, but also requires more memory than you might actually need for your game.

Let’s take an example of how this works. With your PerformanceTest-RGBA8888 project still open, build and run your project on your iOS device and select the Memory option in the Debug Navigator (CMD+6). You should see something similar to the following:

Depending on the artwork you are using for your game, you may be able to get away with much lower quality settings for your artwork to decrease the memory overhead. For example, the RGBA4444 format uses 4 bits for each of red, green, blue and alpha channels and requires half the memory of the same image stored using RGBA8888. If your game’s textures look OK in RGBA4444, that is a big savings! Changing the texture atlas pixel format in Xcode You can change Sprite Kit’s default pixel format for texture atlas generation directly in Xcode. Once you have at least one .atlas folder in your project, Xcode will show the options for texture atlas generation.

Select the PerformanceTest project in the Project Navigator and click on Build Settings. Scroll down to Sprite Kit Deployment Options, or just search for texture, and you will see the following:

14 iOS Games by Tutorials Chapter 25: Performance: Texture Atlases

Here you can turn texture atlas generation on and off and set the pixel format that Xcode will use when generating texture atlases.

Choose the RGBA4444_COMPRESSED option here. Sprite Kit will automatically lower the quality of your images the time you build and run.

Note: The compressed formats you see in the Xcode dropdown are only how the texture atlas will be stored on disk (flash storage) and not in memory. If you chose RGBA8888_COMPRESSED, Xcode will gzip the normal RGBA8888 texture atlas. This saves you a little space on your game’s bundle size at the expense of a slightly longer loading time for the texture atlas, because it needs to be decompressed. Remember that in memory the images are stored uncompressed.

With the option key pressed down, select Product\Clean Build Folder and delete the PerformanceTest app from your device.

Build and run the project and you will see it run just as before – but if you zoom in or look closely, you might notice the colors aren’t quite as crisp as before. Also, if you switch to the Debug navigator (CMD+6) and select the Memory option, you’ll see the memory load has decreased:

It is only a slight decrease as this project uses a very small texture atlas, but for your games you may notice a large savings.

15 iOS Games by Tutorials Chapter 25: Performance: Texture Atlases

You might have seen that there were many options to choose from besides RGBA8888 and RGBA4444. Let’s take a deeper look at each option so you better understand which to choose when. More about color formats The diagram below shows the image quality degradation of the RGB formats supported by Xcode and the TextureAtlas tool (which you’ll learn about shortly):

Take a close look at the images and you can make the following observations:

• RGBA8888 is a 32-bit pixel format using 8 bits for each of red, green, blue and alpha. This is the highest quality image with no degradation. • RGBA4444 is a 16-bit pixel format using 4 bits for each of red, green, blue and alpha. Since the sample image above uses only a small number of colors, you can’t discern much of a difference. However, if you look very closely at the gray on the wings you may notice some slight artifacts as a result of the smaller color space. • RGBA5551 is a 16-bit pixel format using 5 bits for each of red, green and blue, and 1 bit for alpha. This means the colors can be sharper, but pixels must be

16 iOS Games by Tutorials Chapter 25: Performance: Texture Atlases

either fully transparent or fully opaque, which removes the gradient along the edges so that they look more jagged. • RGBA565 is a 16-bit pixel format using 5 bits for red, 6 bits for green and 5 bits for blue. This is a great format to use for images that don’t have any transparency, such as full-screen background images. Of course, this image does have transparent areas, which simply become black. Keep in mind that these images look much larger on this page than they would in a game, which means you can see the image artifacts more easily here. For this particular example, if it were up to me I’d choose RGBA4444. It looks almost as good as RGBA8888 but uses half the memory!

This image works particularly well for RGBA4444 because it doesn’t make much use of gradients. In general, the more you use gradients, the more noticeable the difference between 32-bit and 16-bit will become. For example, consider this rainbow image:

In the rainbow image, the difference between RGBA8888 and RGBA4444 is quite noticeable because gradients use a wide range of colors and limiting the colors results in a striping effect. When making artwork for mobile devices, it’s a good idea to limit your use of gradients to avoid this problem. If you take a closer look at the ship image earlier, the artist kept this in mind and limited the colors in the ship to a small number so it would look great even at lower bit depths.

Whatever you choose for your output texture atlas format in Xcode will apply to all texture atlases in your game. But what do you do if you want to have one texture atlas use a high-quality format like RGBA8888 and another use a lower quality format like RGBA4444? Is this possible?

17 iOS Games by Tutorials Chapter 25: Performance: Texture Atlases

The answer is yes, but you have to venture behind Xcode’s wonderful GUI and into the world of the command line.

Manual texture atlas generation Xcode 5 also allows you to create the texture atlases for your project manually via a command line tool called TextureAtlas. This tool is located inside of the Xcode App Bundle, under the following path:

/Applications/Xcode.app/Contents/Developer/usr/bin/TextureAtlas

This may already be on your path if you have installed the Xcode command line tools, but if not you can give the full path to TextureAtlas to run it.

One useful feature of running TextureAtlas via the command line is that you can force the pixel format of the texture atlas being generated.

Above you can see that the RGBA8888 format is the default for all texture atlases created by Sprite Kit, although there is support for lower quality pixel formats as well.

Note: At the time of this writing, the help text for TextureAtlas contains a slight error. All formats other then the default RGBA8888 are stored as a compressed gzip archive on disk, just as you saw in the Xcode GUI options. However, the help text fails to list the word “compressed” in formats 3-5.

Testing out TextureAtlas via Terminal To get a better feel for the TextureAtlas tool, it is useful to run it manually via the command line (rather than via the Xcode GUI or a script). 1. Create a folder on your Mac where you can save some texture atlas files, such as ~/Desktop/Textures. 2. From the chapter resources, copy the TextureTest.atlas folder into the new folder you just created. 3. Start Terminal and cd into the folder you just created, such as ~/Desktop/Textures.

18 iOS Games by Tutorials Chapter 25: Performance: Texture Atlases

4. From the Terminal command line, execute the following command, changing the paths to match the folder name you created:

/Applications/Xcode.app/Contents/Developer/usr/bin/TextureAtlas -v -f 1 TextureTest.atlas

This creates a texture atlas for the sprites in the TextureTest.atlas folder, using format 1, which is RGBA8888 uncompressed. Note the input folder contains both normal and retina-sized (@2x) sprites.

After issuing the command, you will see results similar to the following:

Loading texture file: ...Desktop/Textures/TextureTest.atlas/asteroid-medium.png. Loading texture file: .../Desktop/Textures/TextureTest.atlas/enemy-ship.png. Loading texture file: .../Desktop/Textures/TextureTest.atlas/player-ship.png. Generated texture atlas size [124, 133]. Extrude texture: enemy-ship.png Extrude texture: player-ship.png Extrude texture: asteroid-medium.png Writing texture atlas .../TextureTest.atlasc/TextureTest.1.png. Loading texture file: .../Desktop/Textures/TextureTest.atlas/[email protected]. Loading texture file: .../Desktop/Textures/TextureTest.atlas/[email protected]. Loading texture file: .../Desktop/Textures/TextureTest.atlas/[email protected]. Generated texture atlas size [243, 261]. Extrude texture: [email protected] Extrude texture: [email protected] Extrude texture: [email protected] Writing texture atlas .../Desktop/Textures/TextureTest.atlasc/[email protected]. Writing texture atlas plist .../Desktop/Textures/TextureTest.atlasc/TextureTest.plist.

Once the command completes, open the ~/Desktop/Textures folder or your own equivalent in Finder and you will see the output folder and texture atlases created by TextureAtlas. The created texture atlas folders always have the original folder name with a “c” suffix:

19 iOS Games by Tutorials Chapter 25: Performance: Texture Atlases

Inside the .atlasc folder there are always at least two files: 1. The texture atlas images (pngs, or pvr.gz if compressed). These are the packed images for the texture atlas. Xcode will automatically split normal and retina images into separate atlases for you and will automatically create additional atlases if you go above the 2000x2000 pixel limit. 2. A property list (plist) file. This file contains instructions to Sprite Kit for how to cut out your images from the texture atlas image(s). Let’s take a closer look at this. Xcode contains a great plist editor that you can use for inspecting the output from the TextureAtlas tool. Open TextureTest.plist in Xcode and expand the items by clicking on the triangle icon to the left of the plist keys, as shown below.

20 iOS Games by Tutorials Chapter 25: Performance: Texture Atlases

In this screenshot you can see that enemy-ship.png is located at coordinates (1,66) inside of the TextureTest.1.png file and that it is (79,66) points in size. You can also see that it is not rotated inside the texture atlas png. Sprite Kit uses this information behind the scenes when you use texture atlases. Creating a texture atlas via the TextureAtlas tool If you need to have multiple texture atlases in differing pixel formats your best option is to create them via the command line through Xcode. You can add a new Run Script Build Phase to your Xcode project.

With the PerformanceTest project selected in the Project Navigator, go to Build Settings and set the Enable Texture Atlas Generation option to NO.

You don’t want Xcode to generate the texture atlases automatically anymore since you will be doing that via a script.

Next switch over to the Build Phases panel (next to Build Settings) and select Editor\Add Build Phase\Add Run Script Build Phase.

Note: If you are used to Xcode 4 and earlier, in Xcode 5 Apple has removed the + button for adding build phases. Now the only way to add a build phase is via the Editor menu.

Drag the newly created build phase above Copy Bundle Resources and re-name it to Create Texture Atlas by clicking once on the build phase name.

21 iOS Games by Tutorials Chapter 25: Performance: Texture Atlases

At this point you have an empty script that will run every time you build your app. All you need to do now is to add the script code to create each texture atlas.

Open the Create Texture Atlas build phase and add the following inside the shell script box. Although it may look like multiple lines on this page, you must enter this as a single line.

/Applications/Xcode.app/Contents/Developer/usr/bin/TextureAtlas -v -f 3 "${SRCROOT}/PerformanceTest/AllElements.atlas" "${TARGET_BUILD_DIR}/${EXECUTABLE_FOLDER_PATH}"

This uses the TextureAtlas command line tool to create a texture atlas for the AllElements.atlas folder, using the RGBA4444 option you learned about earlier.

Rebuild your project by choosing Products\Clean and then Products\Build. Look in the build results and you will see a line for the creation of the texture atlas.

Build and run. The app should run as usual, but this time you have fine-grained control of the options passed to TextureAtlas on a per .atlas basis.

Using a build script and the command line options of the TextureAtlas tool you can customize exactly how Xcode generates each texture atlas in your game and use the lowest possible bit depths that are appropriate for each set of artwork.

Remember that reducing the pixel format of your images is likely the number one improvement you can make to reduce your game’s memory footprint. A word about Texture Packer As you learned in Chapter 15, “Imported Tile Maps”, you can also use a popular third party tool called Texture Packer to generate texture atlases for you instead of using Xcode’s built-in TextureAtlas tool.

The advantage of TexturePacker is it has some neat options not currently in Xcode’s TextureAtlas tool like dithering, which can make your images look better than usual at lower quality pixel format. It also has full command line support, just like TextureAtlas does.

22 iOS Games by Tutorials Chapter 25: Performance: Texture Atlases

Personally we are big fans of Texture Packer, and we recommend that you consider using it as your texture atlas needs grow more complex.

Texture atlas pitfalls As you’ve seen, texture atlases improve performance without requiring any code changes. So drop everything into a single .atlas folder and call it a day, right? Not so fast.

Here’s something you need to know about texture atlases: if you use a single sub- texture from a texture atlas, the entire texture is loaded into memory. If you’re not careful, this can cause your app to use more memory than you may have intended.

To help you understand this better, I have created another starter project called MemoryHog-Starter. You can find it in the resources for this chapter. Open this project in Xcode before continuing. Introducing Memory Hog Imagine you were making a game composed of all the mini-games you have created thus far in this book. Your first inclination would be to put each game’s artwork into its own texture atlas. But what if you wanted to create a special mash- up level using some items from each game?

In Memory Hog, you only need three images: the sleepy cat from Cat Nap, the zombie from Zombie Conga and the yellow car from Circuit Racer.

These three images are inside a texture atlas from each respective game. In the Memory Hog project you will find three .atlas folders named game1.atlas, game2.atlas and game3.atlas. Each of these folders contains a lot of images from one of the mini-games, including a single image that Memory Hog needs.

Memory Hog is built from the Sprite Kit template and all of the code on which you need to focus is inside MyScene.m. Open MyScene.m and take a look at initWithSize:. It simply sets the background color and then creates three SKSpriteNodes, placing the sleepy cat in the screen center, the zombie 100 points to the left and the Circuit Racer car 100 points to the right

23 iOS Games by Tutorials Chapter 25: Performance: Texture Atlases

Build and run Memory Hog on your iOS device. With the game running, select the Debug Navigator (CMD+6) and choose the Memory section on the left panel. Note that Memory Hog is using around 10.1 MB.

That is a lot of memory for just three small images! Let’s see what you can do to clean up Memory Hog and make it a better mobile citizen. Bringing Memory Hog down to size To reduce the memory footprint of Memory Hog, it is important to understand the process that Sprite Kit goes through when you ask it to create a sprite from an image. For example, consider this command in Memory Hog:

SKSpriteNode *cat = [SKSpriteNode spriteNodeWithImageNamed:@"cat_sleepy"];

Sprite Kit will look for the “cat_sleepy” image in the following order: 1. First it will check to see if there is a single file in the App Bundle called “cat_sleepy.png.” (More specifically, it looks for an appropriate variation for the current device, such as “[email protected]” for a retina display). 2. If no such single files exist, it will then look in the plist files for the texture atlases in your app’s bundle to see if any contain an appropriately named file. 3. If more then one texture atlas contains the image, Sprite Kit will choose the first one it finds. In tests, this seems to be based on the names of the atlases, sorted alphabetically, but it may be a bad idea to rely on this when designing your games in case the behavior changes in future versions of Sprite Kit. If you want greater control over which texture atlas Sprite Kit uses, you can use the SKTextureAtlas and SKTexture classes described earlier in this chapter. Memory Hog’s memory hogging is due to the fact that each of the three images is in a separate texture atlas, so Sprite Kit is loading three large texture atlases when all you need are three small images. To fix this, you will create a texture atlas that contains only the three images you need for the scene.

In the resources for this chapter, locate the 3elements.atlas folder and drag it into the Memory Hog project in Xcode, under the Images group. Your Memory Hog project should now look as shown below:

24 iOS Games by Tutorials Chapter 25: Performance: Texture Atlases

Build and run the updated version of Memory Hog on your iOS device. While the game is running, switch over to the Debug Navigator (CMD+6) and note the memory usage.

Memory Hog’s footprint went from 10.1MB down to a much more reasonable ~5.6MB, but why?

Sprite Kit searched the texture atlases for the file names and the first time it found each file, it was in 3elements, so it never needed to load any of the larger atlases. Of course, if 3elements had been named “three_elements,” your app would still be using 10.1MB of memory due to Sprite Kit searching texture atlases alphabetically for a match. Once again, this behavior is subject to change so should not be relied upon.

There are two takeaways from this section: first, try to keep sprites that you will use together in a scene inside the same texture atlas. Second, if you have images with the same name in multiple texture atlases, Sprite Kit will probably load the atlas whose name appears first alphabetically.

But when you have a situation like this, it’s better not to rely on behaviors like that and instead manually load the correct texture atlas, which is what you’ll do in the next section.

25 iOS Games by Tutorials Chapter 25: Performance: Texture Atlases

Manually loading texture atlases As you learned earlier, you specify an exact texture atlas and texture to use with the SKTextureAtlas and SKTexture classes. Let’s give this a shot in Memory Hog.

Open MyScene.m and change initWithSize: to look like the following (changes highlighted):

- (id)initWithSize:(CGSize)size textureAtlases: (NSArray *)textureAtlases { if (self = [super initWithSize:size]) {

_start = CACurrentMediaTime(); _textureAtlases = textureAtlases;

self.backgroundColor = [SKColor whiteColor];

CGPoint screenCenter = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame)); SKTextureAtlas *textureAtlas = [SKTextureAtlas atlasNamed:@"3elements"];

SKTexture *catTexture = [textureAtlas textureNamed:@"cat_sleepy"]; SKSpriteNode *cat = [SKSpriteNode spriteNodeWithTexture:catTexture]; [cat setPosition:CGPointMake(screenCenter.x, screenCenter.y + 50.0)]; [self addChild:cat];

SKTexture *zombieTexture = [textureAtlas textureNamed:@"zombie1"]; SKSpriteNode *zombie = [SKSpriteNode spriteNodeWithTexture:zombieTexture]; [zombie setPosition:CGPointMake(screenCenter.x - 100.0f, screenCenter.y + 50.0)]; [self addChild:zombie];

SKTexture *carTexture = [textureAtlas textureNamed:@"car_1"]; SKSpriteNode *car = [SKSpriteNode spriteNodeWithTexture:carTexture]; [car setPosition:CGPointMake(screenCenter.x + 100.0f, screenCenter.y + 50.0)];

26 iOS Games by Tutorials Chapter 25: Performance: Texture Atlases

[self addChild:car];

//[self loadRandomImageFromAllGameAtlases];

} return self; }

The first new line creates a reference to the 3elements texture atlas in memory.

Then for each image, you retrieve the appropriate SKTexture from the 3elements texture atlas. You then use that to construct the SKSpriteNode, rather than via spriteNodeWithImageNamed:, as before.

As you learned in Chapter 13, “Beginning Tile Maps,” using SKTextureAtlas also reduces the number of Objective-C objects your app uses and hence its memory usage. You won’t notice it in this app because you’re only creating three objects, but if you were showing the same image many times, such as in a tile-based game, you would see a significant memory savings.

Build and run Memory Hog on your iOS device and check the memory usage under the Debug Navigator (CMD+6). It should be back to ~5.6MB again. Understanding batching logic The above example covered the best-case scenario, in which you organize your images so there is one texture atlas per scene. In this way, all bind and draw calls for your game’s scene will be batched.

However, in game development best-case scenarios are rare, and you may in fact need several texture atlases if your scene requires a significant amount of artwork. In the case of multiple texture atlases per scene, you will want to organize your scene logically into layers, as discussed in several of the chapters in this book.

Each layer in your game should be its own SKNode and within each layer you should only use one texture atlas. For example, if you are making a space game, you should consider having one layer for the background objects like asteroids, and one layer for the foreground objects like the ship and lasers. You want to avoid having the images you need spread across multiple texture atlases randomly, which will force Sprite Kit to switch texture atlases multiple times whenever it has to draw a scene.

27 iOS Games by Tutorials Chapter 25: Performance: Texture Atlases

By arranging your game’s sprites in layers in this manner, you enforce z-ordering (i.e. sprites from one texture atlas should always be all behind or all in front of another texture atlas) and hence reduce the number of bind/draw calls. You’ll see an example of this in the next chapter.

There’s one more thing that can break your batching, even if you use a single texture atlas per layer. This was touched upon in Chapter 13, “Beginning Tile Maps,” but it’s important to mention again.

If you have multiple sprites that are all children of the same node, each using a texture from the same texture atlas, you would expect that to draw with a single draw call. However, if some of those sprites have a blend mode of SKBlendModeReplace, for example, while others have a different blend mode, such as the default mode of SKBlendModeAlpha, Sprite Kit will not batch the draws properly.

This occurs because Sprite Kit issues a separate draw call each time it needs to change any rendering setting. In order to avoid that, keep sprites that use different blend modes on different layers, even if they use the same texture atlas.

At this point, you have a solid understanding of texture atlases and are ready to turn toward other areas of improving performance in Sprite Kit games. But before

28 iOS Games by Tutorials Chapter 25: Performance: Texture Atlases you do, how about a quick challenge to take your texture atlas knowledge a bit further?

Challenge: Preloading power There’s just one challenge in this chapter – and it’s to teach you a bit more about preloading textures in Sprite Kit.

When working on real-world games, it’s common to use tons of textures, and sometimes these textures can take significant time to load. To simulate this, open Memory Hog’s LoadingScene.m and replace didMoveToView: with the following:

- (void)didMoveToView:(SKView *)view {

CFTimeInterval start = CACurrentMediaTime(); NSMutableArray * textureAtlases = [NSMutableArray arrayWithCapacity:31]; for (int i = 1; i <= 31; ++i) { NSString * atlasName = [NSString stringWithFormat:@"game%d", i]; // Create texture atlas and add to array SKTextureAtlas * atlas = [SKTextureAtlas atlasNamed:atlasName]; [textureAtlases addObject:atlas]; }

[self startMySceneWithTextureAtlases:textureAtlases];

// TODO: Preload textures... }

This initializes MyScene with a list of all 31 texture atlases, then transitions to the scene immediately.

Next, open MyScene.m and uncomment the line in initWithSize: that calls loadRandomImageFromAllGameAtlases:

[self loadRandomImageFromAllGameAtlases];

MyScene will use this to display a random image from each texture atlas, simulating a game with a large amount of image resources.

Build and run your project on an actual device. You will see that the app takes a few seconds to start up, and in the console you will see something like the following (this output is from my iPhone 5):

29 iOS Games by Tutorials Chapter 25: Performance: Texture Atlases

MemoryHog[1273:60b] First render performed in: 1.98 seconds

Whenever you have a long-running operation like this, it’s always a good idea to show a progress indication screen to the player so they know something is going on and are less likely to get impatient and quit the game.

Sprite Kit comes with a method that allows you to preload textures in the background while still performing animations and other processing in the foreground. Your challenge is to modify Memory Hog to preload the textures in the LoadingScene that runs before MyScene.

Here are some hints for how to accomplish this:

• Inside LoadingScene.m in didMoveToView:, comment out the call to startMySceneWithTextureAtlases:. • SKTextureAtlas has a method named preloadTextureAtlases:withCompletionHandler: that you should use to preload the texture atlases. • You should use the following code block for the completion handler:

CFTimeInterval end = CACurrentMediaTime(); CFTimeInterval diff = end - start; NSLog(@"Loaded texture atlases in: %0.2f seconds", diff); [self startMySceneWithTextureAtlases:textureAtlases];

Once you’ve got it working, build and run your project and you’ll see a loading screen appear a few seconds before the main scene appears:

Then in the console, you’ll see some output similar to the following:

MemoryHog[1560:1603] Loaded texture atlases in: 1.65 seconds MemoryHog[1560:60b] First render performed in: 0.31 seconds

This results in the app being quicker to load and feeling more responsive.

Note that at the time of this writing, there is no method to manually unload an SKTextureAtlas from memory. Sprite Kit will automatically unload any texture

30 iOS Games by Tutorials Chapter 25: Performance: Texture Atlases atlases when they no longer have any active references. This is one of the reasons why the LoadingScene passes a reference to the preloaded textures to MyScene – so the texture atlases aren’t unloaded during the transition.

This is also another reason why it’s important to segment your texture atlases based on how you’re using them – so they can be unloaded when no longer in use!

That’s it for texture atlases! Use them wisely, as they are the single most important approach to optimizing your games.

31 Chapter 26: Performance: Tips and Tricks

By Ray Wenderlich

Sprite Kit does an excellent job of optimizing your game under the hood for great performance. Behind the scenes, Sprite Kit automatically creates object pools, avoids drawing offscreen nodes, creates bitmap font atlases and much more, so your games are fast and efficient without you having to think too much about it.

However, as your games get more complicated, from time to time you will run into performance issues. The goal of this chapter is to show you a few problem areas you might encounter when developing your games, and give you some workaround tips and tricks.

In particular, you are going to work on a game called Bullet Storm. Here’s what it currently looks like:

Bullet Storm is a demo of a side-scrolling space shooter. It’s a good start to a space game, but the performance is terrible. As you can see from this screenshot, it is running at less than 1 frame per second (FPS) on an iPhone 5. This app would be better off as a slide show! iOS Games by Tutorials Chapter 26: Performance: Tips and Tricks

In this chapter, you will debug Bullet Storm to discover its performance issues and then you will solve them. By the time you’re done, Bullet Storm will be running nice and smooth, and you’ll be well equipped to give your own games a performance boost!

Getting started In the resources for this chapter, you will find a project called BulletStorm- Starter. Open the project and build and run on your iOS device.

Note: Remember that it’s important to run on your iOS device when testing for performance, as the artificial conditions of the Simulator will give inaccurate results. This is because your iOS device is running a completely different GPU and different resources than your Mac, and the simulator uses -based rendering. In short – any performance you get from the simulator should not be trusted one way or the other!

You should see a very sluggish game appear (your colors and exact FPS may vary):

While the game is running, switch to the sixth navigator tab – the Debug Navigator. Click the FPS section on the left and you will see the game’s FPS (1FPS on my iPhone 5), as well as how many milliseconds your app is using the CPU or GPU each frame:

33 iOS Games by Tutorials Chapter 26: Performance: Tips and Tricks

As you can see in this screenshot, an overwhelming majority of the time is spent on the CPU: 900-1,000 ms on my iPhone 5. This is generally a sign of a performance problem – you want your game to use the GPU as much as possible so that the graphics hardware can do the hard work.

Obviously something very wrong is happening here, but how can you find out what it is? Well, you could dig through the code looking for issues, but there’s a much better way to find performance problems, using your friend Instruments.

Introducing Instruments Instruments is a handy set of tools built into Xcode that you can use to peek into your app. Instruments has tools that can find memory leaks, check resource usage and – what you’re going to do in this section – analyze your app for performance.

Stop Bullet Storm and go to Product\Profile from the Main Menu (shortcut key ⌘I). The following pop-up will appear:

This displays the various instruments that you can integrate into your app. Here you want to find out what’s taking so long, so choose CPU under the iOS section on

34 iOS Games by Tutorials Chapter 26: Performance: Tips and Tricks the left, and then choose Time Profiler and click Profile. A window will appear that looks like this:

The top panel shows you a graph of the CPU use your app requires over time – notice the constant heavy usage!

The lower panel shows you a percentage-wise breakdown of where the CPU spends its time. You’ll see that the CPU is mostly occupied with a function called Main Thread. Click the down arrow next to Main Thread to display the list of sub-functions called by Main Thread and how much time the CPU spends on each. The panel sorts the sub-functions in order of running time, so keep opening the most expensive item until you dig deep enough to reveal functions that look related to Sprite Kit:

This is one way to gather clues about the problem, but there’s an even easier way. Usually you just want to see what “leaf” methods – that is, the ones at the end of the call tree – are taking up the largest amount of time. To figure this out, click the Invert Call Tree checkbox on the left:

35 iOS Games by Tutorials Chapter 26: Performance: Tips and Tricks

This inverts the order of the tree so that the methods that take the most time are at the top of the tree, and their children are the callers of the methods.

Take a look at the first four methods in this list:

• b2ContactManager::AddPair. This method seems to be related to managing physics collisions. As a general rule, testing for collisions gets more expensive the more objects there are in the game. This gives you a hint to check Bullet Storm to see how many physics objects are in the game at one time – maybe there’s a way you can reduce them. • SKRenderer::preprocessSpriteImpl and SKCSprite::getAccumulatedBounds. These methods seem to be related to processing sprites. As a general rule, the more sprites are in a game, the slower it performs. These methods suggest you should check Bullet Storm to see how many sprites are in the game at any one time – maybe there’s a way you can reduce them, too. • SKCEmitterSprite::update. This method seems to be related to processing particle systems. As a general rule, particle systems get more expensive the more particles they generate. This tells you to check Bullet Storm to see how many particle systems are in the game and how many particles each generates, and see if you can find a way to reduce those. If you are an advanced reader, this is a good chance to challenge yourself: Can you take things from here and find and resolve Bullet Storm’s performance problems? There have actually been plenty of hints about how to solve these issues in the earlier chapters of this book! "

But if you want to walk through it step-by-step, keep reading. Let’s start with the first two hints and peek into Bullet Storm to see if there is a way to reduce the number of physics bodies and sprites.

Touring the code If you haven’t already, spend a few minutes looking through Bullet Storm’s source code to see how it works. Here are a few notes: • There is a class for each of the objects in the game: asteroids, lasers, explosions, enemies and the player. They all derive from a class called Entity.

36 iOS Games by Tutorials Chapter 26: Performance: Tips and Tricks

• Most of the game logic is in MyScene. The code should look quite familiar – it is based on the example projects from other parts of this book! • The game is already set up to use texture atlases (see sprites.atlas), and you learned about why that is so important in the previous chapter. If the game weren’t using texture atlases, its performance would be even worse. I know that’s hard to imagine! " As you’re looking through the code, keep an eye out for any sprites or physics bodies that are created unnecessarily. If you think you’ve found the source of the problem, keep reading to the next section to see if you’re right.

Hint: Remember Zombie Conga!

Reducing sprites and physics bodies You may have come across the following function in MyScene.m:

- (void)spawnAsteroids { for (int i = 0; i < 500; ++i) { Asteroid *asteroid = [[Asteroid alloc] initWithAsteroidType:arc4random_uniform(NumAsteroidTypes)]; asteroid.name = @"asteroid"; asteroid.position = CGPointMake( self.size.width + asteroid.size.width/2 + (i*self.scene.size.width*0.25), RandomFloatRange( asteroid.size.height/2, self.size.height-asteroid.size.height/2)); [_fgLayer addChild:asteroid]; } }

This function creates an asteroid field through which the player must navigate. It creates a large number of asteroids (500 to be exact) offscreen to the right and moves them slowly to the left, across the screen.

This is similar to having a “level file” that specifies the position of each asteroid, and then creating each asteroid at the appropriate offscreen location on startup.

You might not see a problem here. This is an easy and straightforward way to create an asteroid field and Sprite Kit doesn’t draw nodes that aren’t visible on the screen.

37 iOS Games by Tutorials Chapter 26: Performance: Tips and Tricks

However, even when nodes are offscreen, Sprite Kit still needs to do processing on the nodes: running actions, checking for offscreen collisions or processing any attached particle systems, for example. That’s the problem with the asteroids here – Sprite Kit has to perform many calculations on asteroids that aren’t even visible. Apple recommends that you only add a node to the scene graph when:

• It has a reasonably good chance of being rendered in the future. • The node runs actions that are required for accurate gameplay. • The node has a physics body that is required for accurate gameplay. In the case of offscreen asteroids, none of these conditions apply. So you should be able to get much better performance by only creating asteroids when you need them – that is, right before they appear on the screen, just like in Zombie Conga!

To fix this, delete spawnAsteroids and replace it with the following:

- (void)spawnAsteroid { Asteroid *asteroid = [[Asteroid alloc] initWithAsteroidType:arc4random_uniform(NumAsteroidTypes)]; asteroid.name = @"asteroid"; asteroid.position = CGPointMake( self.size.width + asteroid.size.width/2, RandomFloatRange(asteroid.size.height/2, self.size.height-asteroid.size.height/2)); [_fgLayer addChild:asteroid]; }

This is a helper method that creates an asteroid just offscreen to the right.

Then in initWithSize:, delete this line:

[self spawnAsteroids];

And add the following in its place:

[self runAction:[SKAction repeatActionForever: [SKAction sequence:@[ [SKAction performSelector:@selector(spawnAsteroid) onTarget:self], [SKAction waitForDuration:0.25]]]]];

This calls the helper function to spawn an asteroid every 0.25 seconds. Now build and run and you should see a marked performance increase:

38 iOS Games by Tutorials Chapter 26: Performance: Tips and Tricks

From 1 FPS to 14.7 on my iPhone 5 – not a bad start!

However, 14.7 FPS still isn’t great, plus that node count of 10620 looks insane! The next step is to examine the particle systems to see if you can tune down anything there.

Note: Your frame rate and node count will probably vary wildly if you tilt your device to play the game rather than resting it on your desk. That’s mainly because your ship’s bullets will collide with more enemies if you around the screen.

This is another great opportunity to challenge yourself: Can you tweak the particle systems so that they perform a bit better, but still look good? Try it out on your own, and if you get stuck, follow along with the next section!

Reducing particle systems Particle systems perform well in Sprite Kit and you should feel free to use them liberally in your games. However, since particle systems become more expensive as they generate greater numbers of particles, you want to make sure yours generate just enough to achieve the desired effect.

Let’s take a look at one of the particle systems in Bullet Storm. Open BulletStorm\Art\Particles\AsteroidTrail.sks, view the SKNode inspector in the Utilities section on the left, and you’ll see the following:

39 iOS Games by Tutorials Chapter 26: Performance: Tips and Tricks

The important settings to notice are Particles Birthrate, Particles Maximum and Lifetime Start/Range. To review:

• Particles Birthrate represents how many particles are generated per second. In this instance, 400 particles are generated per second. • Particles Maximum represents the maximum number of particles to generate at a time. Here it is set to 0, which means unlimited. • Particles Lifetime/Range represents how long a particle lives before it is destroyed. Here it is set to 2 with a range of 0.4, meaning a particle will live from 1.6-2.4 seconds. To determine the average number of particles onscreen for a given particle system, use this algorithm: • Is Particles Maximum 0? Then the average equals Particles Birthrate x Particles Lifetime. • Is Particles Maximum not 0? Then the average either equals particles maximum or Particles Birthrate x Particles Lifetime, whichever value is lower. In this case, Particles Maximum is 0, so 400 x 2 = an average of 800 particles onscreen per second. That’s a lot for a simple asteroid trail effect – tone this way down by setting the Particles Birthrate to 4. Now it has on average 8 nodes per second, which will still result in a neat effect.

Repeat this for the other effects in the game:

• For EnemyTrail.sks, set the Particles Birthrate from 2000 to 200. • For Explosion.sks, set the Particles Birthrate from 5000 to 500. • For PlayerTrail.sks, set the Particles Birthrate from 300 to 30. That’s a lot fewer particles! Build and run, and you’ll see another performance improvement:

40 iOS Games by Tutorials Chapter 26: Performance: Tips and Tricks

The game is almost up to 60 FPS on my iPhone 5 at this point. And it still looks great – some might say even better than before!

Switch to the Debug Navigator again (the sixth navigator tab), and look at the FPS section. You’ll see that now the game only spends 13.6 milliseconds using the CPU, and there’s a much better balance between CPU and GPU usage:

Now let’s check the profiler results. Stop the app, run it under the Time Profiler again and make sure Invert Call Tree is checked:

You will notice the following changes from the last time:

41 iOS Games by Tutorials Chapter 26: Performance: Tips and Tricks

• b2ContactManager::AddPair is no longer on the list, which means that performance calculations are no longer part of the bottleneck. Just-in-time object spawning for the win! • mach_msg_trap is on the list, which means the CPU is actually idle a fair percentage of the time. This is a good thing – it means you’re not using up all of the CPU! • SKRenderer::preprocessSpriteImpl, SKCSprite::getAccumulatedBounds, and SKCEmitterSprite::update are still on the list, but a lot less so than before. That means your game is spending most of its time processing sprites and particle systems. If you needed to optimize still further, you could look for ways to use fewer sprites and particle systems – but for now, performance is pretty good. Bullet Storm is running well enough that we’ll stop here. For your own games, you can run through a similar process using Instruments. However, your problems may differ from the ones just covered. The following section is an overview of other types of performance bottlenecks you may encounter, and gives you some tips and tricks for how to resolve them.

Other performance tips and tricks Use effect nodes and sparingly As mentioned in Chapter 12, “Effect Nodes and Core Image”, using effect nodes and Core Image in your games can result in some amazing effects, but they can also consume a lot of system resources.

Here are a few workarounds to consider if you have an effect node-related performance issue:

• Are you filtering the lowest-possible granularity? For example, applying a filter to the entire scene is a lot more expensive than applying a filter to a single small sprite or even a single layer of sprites. Make sure you’re only filtering exactly what you need to filter. • Can you rasterize the effect? SKEffectNode has a property called shouldRasterize. This is set to NO by default, which means that each frame, Sprite Kit discards the previous result and re-applies the effect. If you set this to YES, it caches the image and reuses it until one of the SKEffectNode’s children nodes change. This is great to use if you’re applying an effect to something that doesn’t change often, like a background image – it can result in much faster performance. • Are there pre-rendered or “fake” alternatives? In cases where you try the previous two tips and your game still doesn’t perform well enough, consider using an alternative to effect nodes. Is there any way you can pre-render the effect into a sprite that you ship with the app? Or fake it by some combination of pre- rendered sprites overlaid on top of each other?

42 iOS Games by Tutorials Chapter 26: Performance: Tips and Tricks

• Can you reduce the size of the effect? In cases such as mask nodes, it often seems easiest to align your mask with your nodes by making them all the same size and then giving them all the same position. However, try to use as little transparent space as possible because transparent pixels add processing time. Instead, trim away any unused areas of your masks and adjust their positions to align them appropriately. If you want to play around with effect node optimization, you’re in luck – a challenge awaits you at the end of this chapter! Object pooling In the games in this book, whenever you need to create a new object (like a laser or an explosion effect), you simply create a new object at that time.

However, on iOS devices, it is expensive to allocate objects at runtime. One way to improve performance is to pre-allocate an array of objects and grab the next available object when you need it.

Note that Sprite Kit seems to do some object pooling for you behind the scenes, so it’s not as critical to implement object pooling yourself when using Sprite Kit as compared to other game frameworks. However, if you find that a large amount of your game’s time is spent in allocation routines, it might pay off to implement some object pooling.

If you want to play around with this, more good luck – there’s a challenge for that at the end of this chapter, too! Perform long-running operations in the background By default, everything in Sprite Kit runs on the main thread. If you have a computationally intensive operation, such as a complicated pathfinding algorithm, you may wish to perform this on a background thread. There is an easy way to run a block of code on a background queue in Sprite Kit: through the runBlock:queue: action. Use texture atlases – and organize them wisely This is probably the most important tip – which is why the book dedicates an entire chapter to the matter. If you haven’t already, be sure to read Chapter 25, “Performance: Texture Atlases.” Keep physics as simple as possible As you saw with Bullet Storm, there is a cost associated with using the physics engine. Here are a few rules of thumb:

• The more physics bodies, the more expensive for performance. Consider making physics bodies only for sprites that actually need them. If a sprite doesn’t engage in collision or contact detection, then it doesn’t need a physics body. You

43 iOS Games by Tutorials Chapter 26: Performance: Tips and Tricks

may be able to design your gameplay in a way to reduce the requirements for physics bodies as well. • Prefer static physics bodies to dynamic ones. That is, if you know an object will not move, set its dynamic property to NO. This allows the physics engine to perform various optimizations that increase performance. • The more vertices in your physics bodies, the more expensive for performance. Consider making a simplified collision shape for your sprite – it doesn’t have to match the sprite’s shape exactly. You’ll find that the faster your objects move, the less exact the physics shape needs to be to give a visually satisfying collision. Remember, you’re trying to make a game, not a real-world physics simulation. • Use usesPreciseCollisionDetection sparingly. This is a flag you can set on physics bodies to prevent fast-moving bodies from passing through other bodies within a single frame. It sounds good, but it does have a performance cost, so usually you want to set this only when you actually need it. And that’s it for performance tips and tricks – and for the technical content of this book! Take a bow, take a break, and get ready for one last treat: learning how to make 2D art for your game.

But if you’ve got to have “one last bit of coding,” continue on with these challenges!

Challenges

There are two challenges in this chapter – one to add some SKEffectNode improvements to Bullet Storm, and one to add some object pooling.

If you get stuck, you can find solutions in the resources for this chapter – but as always give them your best shot first! Challenge 1: SKEffectNode improvements Currently Bullet Storm is applying a random hue adjust effect to the entire scene. Applying a filter to the entire scene is one of the most expensive things you can do with Core Image, and it’s not really necessary for this game. Your challenge is to modify the game so that it filters the background layer only.

Here are a few tips:

• In MyScene.m inside initWithSize:, comment out the lines that set the filter and shouldEnableEffects on the scene. • Still inside initWithSize:, in the for loop that creates the background sprites, create a new SKEffectNode for each background sprite and call it bgParent. • Set filter on bgParent to the Core Image filter. • Set shouldEnableEffects on bgParent to YES.

44 iOS Games by Tutorials Chapter 26: Performance: Tips and Tricks

• Set name on bgParent to @”bg”. • Set the position of bgParent to be CGPointMake(i * bg.size.width, 0). • Set shouldRasterize on bgParent to YES. • Add bg as a child of bgParent. • Add bgParent as a child of bgLayer. • Comment out the four older lines that set the bg’s position, name and zPosition and added it as a child of the bgLayer. Build and run, and you should have a version of the game that has faster SKEffectNode performance! For an even greater challenge, try to find proof of the improvement before and after using Instruments. Challenge 2: Laser object pooling The objects that you create most frequently in Bullet Storm are lasers, so your challenge is to pre-allocate and reuse a bunch of laser sprites instead of continuously allocating them.

Here are a few hints on how to accomplish this:

• In MyScene.m, create a new function called spawnPlayerLasers. It should fill the premade _playerLasers array with 100 laser objects. Then the function should set each laser object to hidden and add it to the _fgLayer. • Call spawnPlayerLasers in initWithSize:. • At the beginning of spawnPlayerLaser, instead of creating a new laser each time, loop through the _playerLasers array. If you find a laser that isn’t hidden, continue using that laser and set hidden to NO. Also comment out the line in that method that adds the laser to the _fgLayer, since the laser should be there already. • In Laser.m’s cleanup method, comment out the removeFromParent line. Instead, set physicsBody to nil and hidden to YES. Build and run, and you should now have an even faster version of the game with object pooling! For an even greater challenge, try to find proof of the improvement before and after using Instruments.

And that’s a wrap! Congratulations for making it through to the end. Now it’s time to switch gears and get creative – it’s time to draw! "

45 Chapter 27: Making Art for Programmers

By Mike Berg

So far in this book, you have created some great mini games, but they’ve all used premade art that I made for you. You may wonder how you can get art like that in your games – that’s what this chapter is all about!

These days, in order to succeed on the , not only does your game need to be fun and innovative, but it needs to look great too. This is a problem for many aspiring game developers – because although you may be great at programming an awesome game, you might not be so great at making it look good. There’s a reason many games feature doodle or stick man art! "

The good news is you have two solid options as a game developer – you can either hire an artist to help out, or you can make the art yourself. After all, making art is a skill you can practice and get better at, just like anything else.

In this chapter, I’ll first help you decide whether you’d prefer to hire a game artist, or do it yourself. In the event you choose to do it yourself, I’ll show you how to create cartoon artwork for your video game in a similar style to the art you’ve used in this book so far:

I’ll also give you some tips on how you can continue to learn and grow your skills as a game artist. My goal is to give you a solid starting point so your games can look as great as they play! iOS Games by Tutorials Conclusion Choose your path: hire or DIY? When deciding how to acquire art for your game, you have two basic choices: you can hire an artist or or do it yourself. Let’s go over each option in turn. Hire an artist Here are the advantages of hiring an artist:

• Work with a pro. If you hire an artist, you can hire someone who is already great at his/her craft, and likely has been already practicing for years. They can focus on what they’re good at, leaving you free to focus on your own specialty – likely programming! • Choose your style. Different artists have different styles – and your game might benefit from a certain type of art style. By hiring an artist, you can look around and find an artist who’s style has the perfect fit for your game. • Rapid development. If you have to make the art as well as program the game, you’ve just doubled your development time. Obviously, splitting up the work can save a lot of time, allowing you to get your game to market quicker. • Collaboration. Sometimes working with an artist can actually help improve your game, as you bounce ideas off each other and feed off each other’s energy and passion for the game. Think of the best games you’ve seen in the past – I bet most of them were made by a team of at least 2! Think this option is for you? If so, skip ahead to How to find and hire an artist. Do it yourself Here are the advantages of doing it yourself:

• Save money. Sadly, most artists are not willing to make art for your game out of the kindness of their heart or promises for future money – they’ll want cold, hard cash. And sometimes that is the very thing that indie game developers lack. If saving money is on your mind, doing it yourself might be only option. • Build skills. A lof of indie developers find the whole process of making a game fun and exciting, and want to learn the skills involved in every step of the process. If this sounds like you, maybe you want to make art just for the experience and skills you’ll pick up along the way. • Lack of dependencies. Working with an artist does introduce a delay into the process. If you need a piece of art right away, you’ll need to wait until the artist is awake/available to work on it/etc. If you make the art yourself (or at least know enough basics to make some placeholders), you can keep moving at the rapid speed that game development often entails. • Glory and honor. The final benefit of doing it yourself is the pure bragging rights. “See that game? Yeah, I programmed it AND made all the art myself. Booyah.” Just be prepared for a long development cycle! "

47 iOS Games by Tutorials Conclusion

Think this option is for you? If so, skip ahead to Getting started.

How to find and hire an artist Many game developers struggle with finding an artist. Here are some tips to get you in touch with a suitable artist as quickly as possible. Conferences and meetups As with looking for work, one of the best ways to find an artist is through networking: you meet one in person at an event in your field, or have one recommended to you by a friend or colleague. How to network? In a nutshell, get yourself out to conferences, local meet-ups and user groups.

Here are some recommendations of good conferences to attend:

• Game Developers Conference (GDC) • Apple’s Worldwide Developers Conference (WWDC) • 360iDev • Unite As for meet up groups, the best thing to do is to search meetup.com for your local area. The best meetups are game developer, artist, or iOS hangouts.

Another good place to check is game developer forums like http://forums.tigsource.com/ or http://www.gamedev.net/ to see if there are any local meetups or game jams in your area. Twitter Many game developers hang out on Twitter. While you won’t necessarily get to know someone personally on Twitter, it’s a great way to expand your list of developer contacts around the world, people who you may eventually meet at a conference or event.

Be an active Twitter user and get to know people’s work. The larger your network of developers, the easier it will be for you to find someone with the skills you need when the time comes. Search for portfolios Do a web search for portfolios of the style you require: “pixel art portfolio” or “fantasy cartoon art portfolio”. You know what you’re looking for, and will quickly see the range of quality available. This will help you make a choice even if you’d rather go with a personal recommendation.

Here are some additional online resources for portfolios:

48 iOS Games by Tutorials Conclusion

• A lot of artists post their work on Deviant Art – it’s often a great way to find up and coming artists: http://www.deviantart.com/ • If you’re into pixel art, look no further than Pixel Joint. It’s a great community of pixel artists who regularly post their work and portfolios: http://www.pixeljoint.com/ • 3D Total has a terrific gallery that’s organized into categories (Character, SciFi, Fantasy, Cartoon, etc). Their forums are also very active: http://www.3dtotal.com/index_gallery.php • The Polycount forum has portfolios that are specific to game art: http://www.polycount.com/forum/ Call for applications Post your project needs on your website and on a few job boards. Here are a few web sites and boards to post jobs at:

• Concept Art has a job board with a lot of game illustrators: http://www.conceptart.org/forums/ • Gamasutra has a job board: http://www.gamasutra.com/jobs/ • 3D Total, Polycount, Pixel Joint, GameDev.net, and TigSource (mentioned above) also have job boards. Of the applications you receive, discard those without good portfolios, regardless of their experience. A portfolio should demonstrate the artist’s ability to do the job in the style you want it done. Does this really work? As an example, Ray and I first got to know each other via Twitter. He looked at my online web portfolio a few times, so he was familiar with my work. A few years ago, we met in person at a conference. Over the years we stayed in touch, and that’s how I came to work on this book!

The moral of the story is get to know artists you admire, preferably in person, and make connections – you never know when you might want to work together on a project some day!

Paying your artist As I mentioned earlier in this chapter, most artists aren’t willing to work for free. You need to find some way to reimburse them for their time and effort – this section will cover what to expect, and my personal recommendations.

49 iOS Games by Tutorials Conclusion

Revenue share contracts Revenue share contacts are those where you promise an artist a percentage of the income for your game, but no money up front.

These types of contracts are often appealing to indie game developers with little money to spend, but it’s very hard to find an experienced artist who is willing to take these kind of deals. This is because many artists have been burned with promises for revenue share, only to come up with nothing to show at the end!

The only time these types of deals seem to work is if you have a strong pre-existing relationship and trust with the artist. For example, if you have a good friend or significant other who’s an artist, you might be in business. Also, they’ll probably need to be pretty passionate about the project for it to work out – otherwise they might lose motivation and interest.

If you are not in this situation, you’ll probably have to pay the artist up front. If you think of it, that can be a good thing – if your game does well, you get to keep the profits for yourself! Fixed quote contracts vs. hourly contracts If you’re going to pay the artist up front, you have a choice – you can either pay them a fixed amount up front, or by .

The advantage of fixed quote contracts is you know how much you are going to spend up front.

However, I personally recommend against fixed-quote contracts. Game dev projects are ever-evolving; at the beginning of a project, it’s impossible to know exactly how much art the project will eventually require. As soon as the artist’s time goes over that fixed quote because of evolving to-do lists, his or her interest, motivation and passion for the project are likely to drop like a stone.

Here’s what works for me and my clients. My own method is to provide an estimate based on the initial asset request list. I will then send an invoice for a percentage of that estimate (usually 50%; a smaller percentage if the project is larger), to be paid up front.

I keep very detailed track of my time, and provide the client with regular updates that show how I’ve used my time. I send an interim invoice every time the total owing reaches a certain agreed-upon amount.

This method gives both the client and the artist the freedom to make changes to the to-do list on the fly, which is always necessary while a game is in development. Potential disagreements over cost-value can be headed off before they develop. The client knows exactly what they’re getting for their money and the artist stays motivated and involved in the process.

50 iOS Games by Tutorials Conclusion

Price expectations

People often ask me, “how much do artists charge to make art for a game?” If you’re hiring an experienced artist, you can expect to pay anywhere from $30-$90 per hour. At the time of writing, my own rate is $60 per hour.

Generally, the more skilled the artist, the more you can expect to pay. You might find an artist for less, but expect their experience and the overall result to be commensurate. “You get what you pay for” is an old adage for a reason.

There’s also great value in finding an artist with experience in making game art. There are many ways an artist can make your life as a developer easier (or harder!), and their level of game development experience is a large factor. For example, an artist who knows about object coordinates, anchor points, texture atlases and overdraw will be able to provide you with graphic files that are ready to use in your tools of choice, with as little extra processing on your end as possible.

Knowledge of games and how they work will help an artist create assets that are efficient and extendible, for long-term re-use and adaptability, in the event of future updates. Occasionally changes to one art asset can require updates to several others; good game artists will know how to keep these of snowball effects to a minimum.

That’s it for my advice when it comes to looking to hire an artist. If this is the route you’ve decided to take, stop reading here and go find yourself an awesome artist.

But if you’re eager to learn more about how to do this yourself, read on!

Getting started The rest of this chapter will show you how to create a cute cat sprite for your game, in a similar style to the other sprites you used in your minigames so far:

51 iOS Games by Tutorials Conclusion

You’ll create the final artwork in Adobe Illustrator using vector shapes. This will allow you to use the artwork at any resolution or size without degrading the quality of the image.

If you don’t already have access to Adobe Illustrator, you can download a free trial here: https://creative.adobe.com/products/illustrator

This will install an interface to Adobe’s Creative Cloud, which lets you try many different Adobe products for 30 days. Once you have Illustrator installed and ready to go, pull out a pencil and paper and get ready to sketch!

Start with a sketch You are first going to make a rough sketch to give yourself a general idea of the shape of the art, so you can trace it in Illustrator later. The type of paper you use for this kind of sketch doesn’t matter — use whatever you have at hand, as long as it’s clear of other markings. Use a pencil to draw.

The cat you’ll be sketching is made up of four main shapes: head, body, front legs and tail. Here’s a quick preview of the four main shapes:

Now follow the instructions below to draw the cat. The exact shapes shown here are just a guide; if you’re comfortable with adapting it as you go, please put your own spin on it!

52 iOS Games by Tutorials Conclusion

Draw an oval for the head. The pear-shaped bottom of the body should be a bit larger than the head, with the upper body/neck stretching up to meet the head.

Near the head and close to the At the bottom of the legs, add edges of the body, draw two an open half-circle for the tops smooth lines that converge a of the feet. bit at the bottom for the legs.

53 iOS Games by Tutorials Conclusion

For the bottoms of the feet, Starting with the leftmost add an arc that’s a bit flatter. curve, define the shape of the tail. Then add a second curve to give it thickness. Cartoon cat tails can be way thicker than real cat tails.

Now that you have the basic Look at each arc of the ear shape for the cat, let’s add separately. Start near the some detail. Cartoon cats can middle of the head and draw have pointy cheeks. Don’t ask an arc slightly up, but mostly why. out. Then curve down and slightly inward to finish.

54 iOS Games by Tutorials Conclusion

Round out the sides a bit, Think of the eyes as egg where the ears meet the head, shapes, tilted inward a bit. and add a bit of height to the The nose is a flat oval. top of the head.

Add a short vertical line under Add large arcs for the irises, the nose with a wide “W” some straight whiskers shape underneath for the pointing slightly upward, and mouth. A wide arc over the don’t forget those eyelashes nose defines the cat’s snout. for extra loveability.

55 iOS Games by Tutorials Conclusion

Moving on to the legs, draw a Cut a small wide triangle out straight line down the middle, of the bottom center of the not quite as high as the outer feet to make them point lines for the legs. slightly outward. Add two short lines on each foot to make toes.

Smooth out the arc for the One at a time, add curved back a bit. Add a line for the points to make up the fur at top of the back leg. the end of the tail. Make them varied in size, with the middle one the biggest.

56 iOS Games by Tutorials Conclusion

Optional: Add a curve near Optional: Erase unnecessary the end of the tail, and curves lines. You only need to do this over the top edge of the paws. if your drawing is very These will define areas with “sketchy” (which is OK!) and white fur. it’s hard to see the final lines, which you’ll be going over in Illustrator.

Getting the sketch into Illustrator Don’t worry if you don’t have a scanner – the camera on your iPhone or iPad works just as well for this purpose. Lay your sketch flat in a well-lit area, and hold your iPhone directly over it. Try to get the angle as square as possible. Line up the edges of your page with the edges of the screen to help with this.

57 iOS Games by Tutorials Conclusion

Email yourself the photo, using the “Large” setting when asked how you want to resize the image. Open Illustrator and select File\New… (CMD-N) to create a new document named cat. Choose Devices from the drop-down list next to the label Profile and then choose iPhone 5 from the drop-down list next to the label for Size. This should result in an image that is 640x1136 pixels, which is the size of an iPhone 5 screen. Click OK.

Select File\Place… and select the file you emailed yourself for the sketch. Leave the checkbox options as they are by default, with only “Link” selected. Click Place to add it to the Illustrator file.

58 iOS Games by Tutorials Conclusion

You will see the “Place” cursor, along with an icon of your image.

Click and drag to draw a box that mostly fills the canvas. This sets the size and position of your placed file.

59 iOS Games by Tutorials Conclusion

Many of the controls you’ll be using to modify your artwork are organized into what Illustrator calls palettes. These are shown on the right side of the screen. To start with, make sure the ones you’ll use most often are visible. Select Window\Workspace\Essentials. If all you see are buttons, click the tiny “Expand Panels” button at the top-right of each panel. Don’t worry if it’s not exactly the same, but you should see an arrangement of palettes something like this:

In the Layers palette (select Window\Layers if you don’t see it), click the empty square next to the “eye” icon on the layer for the cat. This will lock the layer, preventing you from selecting it or moving it accidentally. Click the Create New Layer button to add a layer that you’ll use to hold your vector tracing.

60 iOS Games by Tutorials Conclusion Tracing the sketch with vector lines Before you begin tracing the sketch, you should set your default colors. At the bottom of the Tools palette, there are swatches for the current fill color (the solid box) and stroke color (the box with the thick outline). These fill and stroke colors will be used for any object that is created.

Press D to set the default colors for stroke and fill (white fill, black stroke). Click the fill swatch, which is a white square:

Press the forward slash key (/) to clear the background swatch and make it transparent – a red line will appear through the swatch. Now the Pen Tool will draw black lines with no fill – ideal for creating outlines.

Next, select the Pen Tool (shortcut: P). With the Pen Tool, every time you click you create an anchor point for the curve, and dragging allows you to define the direction and “strength” of the curve for that point. You may be familiar with the concept of a bezier curve from programming – basically this is what this tool lets you create! Click to draw straight lines with sharp corners, click and drag to create curves. A curved point has “handles” that define the direction and strength of the curve. The handle is a dot at the end of the line coming out of the point.

Next follow the instructions below to use the pen tool to trace the ears of the cat, which is a simple 3-point curve. Your first point will be a curve, so start by clicking and dragging, as shown below. And yes, you can edit a line after you’ve drawn it – more on that below.

Click at the start of Click at the tip of the Click at the end of the line and drag ear and drag out the line and drag a toward the upper shorter handles, handle out until the left. roughly line looks right. perpendicular to the first set of handles.

Hold the Command key and click anywhere else on the canvas to finish creating that line. Use the Selection Tool (shortcut: V) to click on the line you just

61 iOS Games by Tutorials Conclusion created. At the top of the screen, increase the stroke width to something more substantial, like 4px.

Continue creating paths for the top of the head and the other ear. The Pen Tool remembers the settings for the last line you selected, so new lines will have the same stroke thickness.

Great work! The Pen Tool can take some getting used-to, but with some practice, you can get your lines created with minimal fuss. Editing a path Your line won’t always look exactly the way you want it on the first try, and that’s ok! It’s easy to adjust the shape of a line to make it exactly the way you want.

To change a line after you’ve created it, use the Direct Selection Tool (shortcut: A) to click on the line. This will highlight the points. Click on a single point to show its handles. Drag the point to move it, or drag the handles to adjust the angle and strength of the curve.

Note: Illustrator has a feature called Smart Guides. If it is turned on, it will attempt to snap points, paths, and even 90 degree angles automatically. It is often easier to edit your lines with this turned off. Select View\Smart Guides (CMD-U) to toggle this feature.

Creating complex lines A line with a mix of curves and sharp corners, like the cat’s “pointy cheeks”, requires one extra step during its creation. Rather than creating curved lines and then editing each sharp corner afterward, you can create these corners while drawing the path. The key is to Option-drag a handle immediately after you create it:

62 iOS Games by Tutorials Conclusion

Click and drag the first Click and drag to create With the Pen Tool still point’s handle downward. the second point. active, Option-drag the handle so that it points roughly toward the next corner.

This method allows you to create almost any shape of line with a single series of mouse gestures, all without having to change tools. Remember, when a line is finished, you can always refine its shape with the Direct Selection Tool.

Use this method to create the rest of corners for this line, as shown here:

Rounding the ends of the lines By now you may have noticed that each line is squared off at the ends. This stands out and looks bad if your lines don’t meet up exactly. Rounding the ends can help make your lines more visually pleasing.

63 iOS Games by Tutorials Conclusion

Press CMD-A to select all. In the Stroke palette (select Window\Stroke if you don’t see it), set the Cap and Corner buttons to Round. If you don’t see the Cap and Corner buttons, click the palette menu button at the top-right and click “Show Options”:

Finishing the outlines Using the skills you’ve learned so far, create the rest of the outlines for the cat, until all your lines are vector paths.

Note: Press CMD-S to save. If you want to have a look at the lines I’ve created by this point, have a look in the Resources folder at the file cat-01- outlines.ai.

Custom stroke widths for a more natural line Now that all your lines are done, your drawing already looks much cleaner! You’re well on your way to creating beautiful, game-ready art. It also looks a little mechanical, though, since all the lines are exactly the same width. You can use the Width Tool (shortcut: Shift-W) to give your art a more hand-drawn look.

Note: The Width Tool is only available in Illustrator CS5 and up.

64 iOS Games by Tutorials Conclusion

With the Width Click and drag to The line is made Tool, hover your make the line thicker at that point, cursor over the tip of slightly wider at that with a smooth the ear. It indicates point. transition to the end it will add a new points. width point here.

Create a default width profile for illustration You may think that was easy, but there’s a way to speed this up even further!

Use the Selection Tool (shortcut: V) to click on the line you just edited. At the top of the screen, you’ll see some options for the current path, including a popup that shows the Width Profile you just created. Click this popup and click Add to Profiles:

Name it Thick in the middle. This creates a reusable Width Profile that you can apply to any path. Press CMD-A to select all the paths in your drawing, and then select your new profile from the Width Profiles popup.

65 iOS Games by Tutorials Conclusion

v

The effect is subtle, so look closely if you don’t think you see it. Now those lines really do look more like they were hand-drawn.

Notice how in the picture above, the path on the left ear (the first one you made) is thicker than the others. If this happened to you, select the thicker path with the Selection Tool and change its stroke width back to 4px in the bar at the top of the screen:

Using other width profiles for different line shapes Your stroke widths may still not look exactly as you want them in certain places. Select all of the eyelashes by Shift-clicking them with the Selection Tool. Click the Width Profile popup and select the triangular profile:

v

Experiment with the Width Tool to customize your lines. Keep going until you’re happy with how they look. The Width Tool is powerful, with several features not covered here. For a more detailed look, watch this video: http://tv.adobe.com/watch/learn-illustrator-cs5/using-variablewidth-strokes/

Note: Press CMD-S to save your file. My version of the file at this point is in the Resources folder, called cat-02-width-tool.ai.

66 iOS Games by Tutorials Conclusion Coloring your artwork After you’re finished tweaking the widths of your lines, let’s add some color. Start by using the Selection Tool to select the outline of the head:

Select Edit\Copy (CMD-C), then Edit\Paste in Back (CMD-B) to create a copy of the paths in exactly the same position, layered behind the current paths. This will be the starting point for creating a colored shape that fits precisely behind the lines that already exist.

Press Shift-X to reverse the fill and stroke colors. Your fill was transparent before, so now your strokes are transparent and your fills are black. It looks a little strange, but we’re about to fix that:

You need to edit these points, but since they’re behind the outline paths (and in exactly the same place) it’s impossible to be sure you’re editing the points for the fill and not the paths for the stroke.

To solve this, select Object\Group (CMD-G) to group the new set of paths and double-click the group to enter Isolation Mode. This lets you work on the contents of the group without any other objects getting in the way.

In Isolation Mode, the rest of your art is faded back a bit, showing that it can’t be selected:

67 iOS Games by Tutorials Conclusion

All these separate paths need to be joined together to make one solid shape that we can color. Use the Direct Selection Tool (shortcut: A) to draw a marquee around the bottom two points to select them:

Select Object\Path\Join (CMD-J) to join the two points. This joins the left and right paths, creating a filled path that’s almost the size of cat’s head, but it’s still open at the top:

Use the Direct Selection Tool to select the top-left point of the path. Shift- click the left point of the curve that forms the top of the cat’s head:

68 iOS Games by Tutorials Conclusion

Press CMD-J to join the points. Your cat’s head should now be completely filled. The path is still open at the top-right, under the ear, but that’s OK. We’re going to merge it with the ear shapes next.

Using the Pathfinder to combine shapes The Pathfinder is a very powerful set of tools that let you combine multiple shapes in interesting ways. We’ll start by using the simplest function – Unite – to combine all three color fills into a single shape.

Switch to the Selection Tool and Shift-click each of the ears to add them to the current selection. In the Pathfinder palette (select Window\Pathfinder if you don’t see it), click the Unite button. This merges all three paths into a single shape.

With the fill shape selected, let’s give it a better color. In the Swatches palette (select Window\Swatches if you don’t see it), select a color for your cat:

Note: If the stroke color changes instead of the fill, press CMD-Z to undo, press X to make the fill color the active swatch, then select your color again.

Double-click outside of your shape to exit Isolation Mode. Your first filled shape is done!

69 iOS Games by Tutorials Conclusion

It’s best to create a separate fill for each basic shape so that when we get to the shading stage, shading objects can be layered behind objects in front. For example, the shading for the body will be layered in behind the shape of the legs. If the fill for the body and legs were the same object, this wouldn’t be possible without doing some extra trimming of the shaded area. This will become clearer shortly.

Use the same method to create a filled shape for the legs, body and tail. Remember the basic steps: 1. Select the paths that create the outline of the area you’re trying to fill with the direct selection tool 2. Select Edit\Copy (CMD-C), then Edit\Paste in Back (CMD-B) to create a copy of the paths in exactly the same position 3. Press Shift-X to reverse the fill and stroke colors 4. Select Object\Group (CMD-G) to group the new set of paths 5. Double-click the group to enter Isolation Mode. 6. As necessary, combine the paths with the Direct Selection tool and CMD-J, or via the Unite button in Pathfinder.

Once you’re done, use the Selection Tool , select the lines and fill for the tail and send it to the back by pressing CMD-Shift-[.

70 iOS Games by Tutorials Conclusion

Note: Press CMD-S to save. Refer to the file cat-03-basic-fill.ai to start from here.

Coloring the eyes Next, add some color to the eyes. Select the outer “egg shaped” ovals for both eyes with the Selection Tool. Copy the paths (CMD-C) and Paste Behind (CMD-B). Swap the stroke and fill colors (Shift-X) to create a filled path with no stroke. Click the white swatch in the Swatches Palette to change the fill color to white.

With the Selection Press Shift-X to Double-click the new Tool (V), click the swap the fill and black shape to enter top arc of the iris. stroke colors Isolation Mode. Press CMD-C to copy it, then CMD-B to paste behind.

71 iOS Games by Tutorials Conclusion

This shape isn’t big Then click once for You need a duplicate enough for the iris. each point shown of the white eye To make it the right here, covering the shape to use for the shape, use the Pen lower part of the eye Pathfinder operation. Tool (P) and click with the new shape. Use the Selection the end point of the Double-click outside Tool (V) to click it. path. the shape to leave Press CMD-C to copy Isolation Mode. and CMD-F to paste in front.

In the Pathfinder Palette, click the “Intersect” button.

Still using the The shapes are Selection Tool, hold combined, leaving Shift and click the just the shape of the shape you just iris. created for the iris.

72 iOS Games by Tutorials Conclusion

With the iris shape Click empty space on Now you need a still selected, click a your document to duplicate of the iris green color in the deselect. Click the shape to use for the Colors Palette. black swatch in the Pathfinder operation. Swatches Palette. Use the Selection Then use the Ellipse Tool (V) to select it. Tool (L) to draw a Press CMD-C and black circle for the then CMD-F to pupil. create the duplicate.

Using the Ellipse Tool (L), draw a white circle for a highlight on the eye. Hold Shift and click You’re left with the Repeat this entire the pupil to have iris and pupil looking process for the other both shapes very nice. eye. selected. In the Pathfinder Palette, click the Intersect button.

Select the curves for the tops of the irises and change them to a dark green.

73 iOS Games by Tutorials Conclusion

Note: Press CMD-S to save. Refer to cat-04-eyes.ai to start from here.

Coloring certain areas You’ll start adding some extra color to your cat by making the end of the tail and the two front paws white.

You need a shape that is white with no stroke. Press D to set the default fill (white) and stroke (black). Make sure the stroke swatch is “on top” of the fill swatch, as shown here:

If it isn’t, press X to switch them, bringing the stroke to the front. Press the forward slash key (/) to remove the stroke.

Using the Pen Tool, draw a curved line across the tail, near Continue the path around the the top. The curve should end of the tail by clicking once extend out past the edges of the for each point. Make sure the tail, as shown. You’ll trim it end of the tail is covered down later. completely. The shape doesn’t need to be closed – the Pathfinder tools work just as well with open paths.

74 iOS Games by Tutorials Conclusion

Use the Selection Tool (V) to Hold the Shift key and click the select the tail, press CMD-C to white path so it is also selected. copy it, then press CMD-F to For the Pathfinder to work, it’s Paste in Front. You’ll now use important that both the tail this copy of the tail shape with shape and the white shape the Pathfinder to make the white you just created are selected, path match the shape of the tail. that they are the only shapes selected, and that they are overlapping.

In the Pathfinder palette, click The parts of each shape that are the Intersect button. not overlapping are trimmed away. What remains is a single shape for the white end of the tail.

A word about layers I’ve spoken a bit about layers and the layering of objects – here’s a closer look at how this works. Look at your Layers Palette – currently there are two layers, one

75 iOS Games by Tutorials Conclusion for your sketch, Layer 1, and one for your vector artwork, Layer 2. Click the disclosure triangle next to Layer 2:

This reveals all the objects that are within that layer:

A single layer can hold any number of objects. An object is a single path or shape. As you can see, you’ve created a lot of objects in Layer 2 already! The Layers Palette shows the objects in order of their layering. Objects at the top of the list appear on screen in front of objects farther down the list. Reordering object layers Object layering can be changed by dragging an object’s name up or down in the Layers Palette, or you can use Object\Arrange\Send Backward (CMD-[) or Object\Arrange\Send Forward (CMD-]). From now on, when I refer to object layers, I mean the layering of objects inside “Layer 2”. You do not need to create new Layers, or change the order of the two primary Layers you have. Getting back to our cat’s tail, the white shape at the tip of the tail is currently sitting in front of the black outlines for the tail. You could press CMD-[ until it’s behind the outlines, but that can get tedious in a document with many objects.

Instead, select the white shape for the end of the tail, press CMD-X to cut it, then select the object you want it to appear in front of (in this case, the color fill shape for the entire tail) and press CMD-F (Paste in Front). This is the fastest way to get an object exactly where you want it in the layer stack.

76 iOS Games by Tutorials Conclusion

Use this method to paste the white tip of the tail in front of the fill for the tail. It should now show up behind the stroke:

v

Follow the same steps to create a white fill for the front paws. As a reminder, here are the basic steps: 1. Use the pen tool to draw a shape that colors the area in the paws you want filled, overlapping the area outside the paws 2. Select the paws, and press CMD-C to copy them, then press CMD-F to Paste in Front 3. Hold the Shift key and click the white path so it is also selected. 4. In the Pathfinder palette, click the Intersect button. 5. Use Object\Arrange\Send Backward (CMD-[) until the white shape is properly behind the black strokes, as you see below.

The last piece to add is an oval around the cat’s mouth and nose. Use the Ellipse Tool (shortcut: L) to create one:

77 iOS Games by Tutorials Conclusion

To get the ellipse into the right place in the layer stack, use the Paste in Front technique to cut the white ellipse and paste it in front of the color fill for the head. This will place it behind all the strokes for the face.

Checkpoint! Press CMD-S to save. If you wish, you can start from here using the file cat-05-tail-and-toes.ai in the Resources folder.

A bit about shadow and light Typically, in-game lighting comes from the top-right. This is because many games have a general progression from left to right, so lighting from the top-right highlights the hero’s face as they progress.

With the light shining from the top-right, shadows will fall on the lower-left areas of any given mass:

78 iOS Games by Tutorials Conclusion

To create shadows like this in Illustrator, you’ll use almost the same Pathfinder technique you used to create the white areas for the tail and paws. Start by using the Selection Tool (P) to select the fill for the body:

You’ll recall that two Drag the currently Hold Shift and click the shapes are required selected shape (the first copy you made of for a Pathfinder topmost one) up and the body shape so that operation. Press to the right a bit – they are both selected. CMD-C to copy it. shown here in black Then press CMD-F so it’s easier to see. twice. I also dragged the bottom-right resize handle up and left a bit to make it smaller.

In the Pathfinder In the Transparency palette, click the palette (select Subtract button. Window\Transparency if you don’t see it), The front shape is What remains will change the opacity to subtracted from the work great for a 30%. back shape. shadow on the body. If you haven’t already changed the color to black, click Fill box in the toolbar on the left to bring it forward, then click the black swatch in the Swatches palette.

79 iOS Games by Tutorials Conclusion

Remember to rearrange the layers. Cut the shadow shape, select the body fill shape, then Paste in Front (CMD-F); as described previously. Use these steps to create shaded areas for the front legs, head and tail. Here is a reminder of the steps to follow:

1. Select the area you want to shade with the Selection Tool 2. Create two copies of the shape. Pressing CMD-C to copy it, then press CMD-F twice. 3. Move one of the copies up and to the right a bit, optionally resizing it. 4. Shift-click to select the original shape as well, and use Pathfinder\Subtract to create a new “shadow area”. 5. Set the color of the “shadow area” to black, and set the transparency to 30%.

80 iOS Games by Tutorials Conclusion

Remember: copy the base shape, paste twice, drag the top shape up and to the right, and use the Pathfinder to subtract it from the first copy. Then change the opacity and make sure it’s layered correctly. Extra shadow details for more depth Adding extra shadows can help define some of the shapes in your art, providing a sense of depth even where there are no outlines. For example, in the image below, you can see a shark-fin-like shape used to show some fur sticking up in front of the ear, with the shaded area forming the inner ear itself.

Create these by drawing a black path with the Pen Tool and then setting its transparency to 30%. Here are the abbreviated steps:

Click and drag. Click and drag. Option-drag the handle.

Click and drag. Option-drag the Click and drag. handle.

81 iOS Games by Tutorials Conclusion

Option-drag the Click once (for a Click and drag. handle. sharp corner with no handles).

Option-drag the Click once on the handle. first point to close the shape.

In the same way, add some depth to the tufts of hair at the end of the tail. Imagine extending the inner line down further into the tail, then curving back up to the tip, and you have the shape for your tail shadows:

Save! Press CMD-S to save your progress. A version of the file at this point is in the Resources folder, called cat-06-shaded.ai.

82 iOS Games by Tutorials Conclusion

Coloring the outlines The final step is to color the outlines. Some pieces will look great with black outlines, but usually, adding color to the outlines helps bring out the color of the object and give it even more depth.

Start by using the Selection Tool to select any one of the black outlines. In the menu bar, choose Select\Same\Stroke Color. This will select all the black lines in the document.

Have a look at the swatches and make sure the stroke swatch is “on top” of the fill:

If it’s not, click on it to bring it forward or press X to swap them. Click on a darker version of your fill color in the Swatches palette to change your stroke color.

Some of your strokes can stay black (the nose) or be dark grey (the whiskers and mouth). Use the Selection Tool (P) to select the strokes you want to change, then click the color in the Swatches palette that you want to use. This is mostly a matter of preference, so play around with the outlines until they look just the way you want.

The cat is now finished. Don’t forget to save! Press CMD-S to do so now.

Note: A finished version of the Illustrator file is in the Resources folder: cat- 07-finished.ai.

83 iOS Games by Tutorials Conclusion

Exporting PNG files In Illustrator, the Artboard refers to the dimensions of the document you are working in. In the beginning of the chapter, we set the artboard to be 640 x 1136, to match an iPhone 5 screen. If we were to export a PNG of our cat now, it would have a lot of unnecessary transparent space around the edges of our cat image.

The Artboard for the cat image needs to be shrunk down to match the size of the cat itself before you export it

Press CMD-A to select all the art on the canvas. Select Object\Artboards\Fit to Selected Art to make the Artboard match the size of the art.

Select File\Save for Web… At the top-right, choose the PNG-24 preset and click Save. PNG-24 will save a full-quality PNG file with transparency. This is the preferred graphic format for all iOS applications.

84 iOS Games by Tutorials Conclusion

iOS games require 2 versions of your graphics, retina and non-retina. Your Illustrator document was created at retina resolution for iPhone (1136 x 640), so start by exporting the retina version of your graphic. Add @2x to the end of the filename (eg. [email protected]) and click “Save”.

Next, create the non-retina version of the graphic, which is scaled down by 50%. Select File\Save for Web again. In the Image Size panel, set Percent to 50 and click Save to create the non-retina version of the graphic. Make sure you use the same filename as the previous step, without @2x – that is, cat.png.

85 iOS Games by Tutorials Conclusion

Congratulations! You’ve taken a blank piece of paper and turned it into a resolution- independent piece of game art, ready to use in your next project.

Challenges Want to brush up your artistic skills some more? Here are two more characters that you can use as guides to practice the techniques you’ve learned in this chapter.

As always, if you get stuck you can find the solutions in the resources for this chapter – but give it your best shot first! Challenge 1: Squeak! Your first challenge is to draw one of the simplest possible characters: a lowly mouse. The shape is nice and simple so you can have a quick practice on going through the steps you’ve learned in this chapter all on your own.

Challenge 2: Woof! For a little more challenge, how about making a dog? This one involves some more complicated shapes, and a bit more lighting and shadows.

86 iOS Games by Tutorials Conclusion

If you’ve made both of these characters, huge congratulations – you now have some solid tools in your toolbelt to make some simple 2D game art!

Be sure to keep experimenting and most importantly, have fun. The key to developing your skills as an artist and a programmer is practice, practice, practice.

If you care to share your results of any the artwork you create after following this chapter, we’d love to see it. Please stop by the book forums and share!

87