I'm a robot

Tag: tutorial - page 1 / 6

UIKit applications often contain animations and lots of graphics. Adding the graphics as single images might consume a lot of memory and impede performance.

Using TexturePacker to create sprite sheets instead:

I've created some powerful classes which allow you to simply load the sprite sheets created with TexturePacker into your application - including code to play animations.

If you use animations that are pre-aligned, you might also have a lot of transparent pixels in your images. While the individual files might not use much memory - due to compression - the RAM usage might be quite big.

If you pack your sprite with TexturePacker this transparency can be removed. The provided CAWSpriteLayer class compensates the missing transparency by moving the sprite into the same spot as if it had its original size.

Using the sprite data

First of all, you need to load the data file created with TexturePacker and the sprite sheet image:


NSDictionary *spriteData = [CAWSpriteReader spritesWithContentOfFile:@"spritesheet.plist"];
UIImage *texture = [UIImage imageNamed:@"spritesheet.png"];

With this you can simply create layers and add them to your current view:

CAWSpriteLayer *layer = [CAWSpriteLayer layerWithSpriteData:spriteData andImage:texture];
[self.view.layer addSublayer:layer];

Static images

To add a static image use:

[layer showFrame:@"staticimage"];

With this you can use all standard operations on layers - like setting the position or applying transformations:

[layer setPosition:CGPointMake(400, 200)];
[layer setTransform:CATransform3DMakeScale(0.5,0.5, 1.0)];

Animations

To add an animation use:

[layer playAnimation:@"CapGuyWalk%04d" withRate:24];

The format of the animation's name is derived from its frame names: This will play an animation with all frames that match CapGuyWalk0000, CapGuyWalk0001, CapGuyWalk0002, ... until no more frames with matching names are found.

The frame rate is set to 24 frames per second.

You can also set animations to repeat:

[layer playAnimation:@"CapGuyWalk%04d" withRate:24 andRepeat:2];

The special value INFINITY will repeat the animation forever.

After an animation is played to the end, you can decide if you want to show the last frame or an empty frame:

[layer setShowLastFrame:true];

Controlling animations

The CAWSpriteLayer has all standard animation controls:

Pause:

[layer pause];

Resume:

[layer resume];

Stop:

[layer stop];

Internal structure

The CAWSpriteLayer consists of 2 nested layers: The outer CAWSpriteLayer which allows you to perform all transformations, and the inner CAWSpriteCoreLayer which handles the sprite display. This is necessary since the inner layer makes use of transformations to implement trimming.

Demo Project

I've created a complete demo project for you - available on GitHub for download.

Source code available for download

git clone git@github.com:AndreasLoew/UIKit-TexturePacker.git
UIKit-TexturePacker.zip UIKit-TexturePacker.tar.gz

I've added a new feature to TexturePacker which helps you to prevent your assets from being stolen. It's called ContentProtection and simply encrypts the images.

Your app or game will still be able to decrypt the data, but somebody else is going to have a hard time getting it done.

In theory it would still be possible for somebody to extract the key from the source code and write some decoder, as the decoder and key have to be stored in your app - otherwise it would not be possible to use the assets in your game at all. But it will take knowledge, time and effort to decrypt your assets. So instead of stealing your assets, it's likely that they go and find some easier prey.

Setting up TexturePacker for encryption

I assume that you already have TexturePacker running to create sprite sheets. So simply open an existing .tps file.

Download the latest TexturePacker - here you'll find a new option on the left: Content Protection. Press the "lock" icon and a new popup opens:

You can enter your own key in the line edit - or simply create a new one by pressing Create new key.

To disable encryption use Clear / Disable.

Save as global key stores the key in TexturePacker as global - using it for decryption in the .pvr viewer and allowing you paste it into other sprite sheets by simply pressing Use global key

It is important that you change the file format to pvr.ccz - which is currently the only file format that supports encryption.

Press Publish and you are done in TexturePacker.

The corresponding command in commandline is --content-protection <key> where the key must be a 32-digits hex value.

Preparing your cocos2d project for content protection

Download and copy the following 2 files inside your cocos2d folder: libs/cocos2d/Support - replacing the 2 files that are already there:

Now set the key in your app. You can do this by placing 4 calls inside your startup sequence before the first sprite sheet is loaded. Try to distribute the calls among several files to make them harder to spot.

If your license key is aaaaaaaabbbbbbbbccccccccdddddddd, you have to split it into 4 parts with 8 digits each:

Each value is a 32-bit part of the whole 128-bit encryption key. It's quite hard to spot inside the app since it's simply another value passed to a function.
caw_setkey_part(0, 0xaaaaaaaa);
caw_setkey_part(1, 0xbbbbbbbb);
caw_setkey_part(2, 0xcccccccc);
caw_setkey_part(3, 0xdddddddd);
Make sure to add the following line to each file in which you use caw_setkey_part:
#import "ZipUtils.h"

If you had to change the file format, make sure to now load the .pvr.ccz file instead of whatever you used before. Also add the new files to your project.

That's it!

Conclusion

Protecting your game assets from content thieves is easy. Using the new ContentProtection feature can be set up in less than 5 minutes!

Apple's requirements on encryption and Content Protection

I am no lawyer & this is no legal statement! My understanding of Apple's iTunes Connect Guide and the Bureau of Industry and Security is that you don't need to get the ERN approval for your app/game if you use TexturePacker's Content Protection. The encryption is used to protect your intellectual property only and is not accessible to the user - excluding it from the regulations.

See the Bureau of Industry and Securitys Encryption FAQ - Question 15 (What is Note 4?):

...
Examples of items that are excluded from Category 5, Part 2 by Note 4 include, but are not limited to, the following:

Consumer applications. Some examples:
  • piracy and theft prevention for software or music;
  • music, movies, tunes/music, digital photos – players, recorders and organizers
  • games/gaming – devices, runtime software, HDMI and other component interfaces, development tools
...

 

Picture taken from iTunes Connect Developer Guide - Adding New Apps (scroll down to "Ready to Upload Your Binary" to find the paragraph about encryption)

Thanks to David Hart: http://hart-dev.com for writing this tutorial.

David Hart is an iOS developer that has released an iPhone puzzle game named GraviMaze on the App Store using Cocos2D and TexturePacker. He’s found a way of integrating TexturePacker with Xcode using Build Rules and would like to tell us about it.

A Small Problem

The standard method for integrating TexturePacker with Xcode is a life saver if you are used to compiling your sprite sheets manually, but it has a few issues. First of all, it does not benefit from Xcode’s ability to compile several files in parallel. It also forces you to include in Xcode the output sprite sheet and data files which should not be under source control - not the cleanest solution.

An Alternative Solution

One solution I’ve come up with is to have the project only include the tps files and to teach Xcode how to compile them into the sprite sheet and data files using Build Rules. The TexturePacker files will now be an integral part of the build process instead of relying on a post-build script. Out of the box, Xcode will not recompile sprite sheets if there are no changes, and will delete them during the Clean process.

Continue reading...

Thanks to Christian Herzog: www.slegg.net for writing this tutorial and creating this awesome importer for Shiva3D!

My first product got published on the ShiVa Asset Store: an extension to support the awesome program TexturePacker by Andreas Löw. If you don’t know of it yet, check it out at TexturePacker. Here is a screenshot of the supplied demo, showing off all the supported features:

Features

Continue reading...

iPhone, iPad, iPod and the screen resolutions

In the beginning developing for iOS was quite simple - there was only one device with a fixed resolution of 320x480. But as the device family grew more and more screen sizes were added.

Here's an overview over the devices:

Device Resolution
iPhone classic, 3G, 3GS
iPod 1st-3rd gen.
320 x 480
iPhone 4, 4S
iPod 4th gen.
640 x 960
iPhone 5
iPod 5th gen.
640 x 1136
iPad1, iPad2
iPadMini
768 x 1024
iPad3 1536 x 2048

Scaling the assets

If you want to support multiple devices you have to plan your assets and screen resolutions for your application. Since quality is important you should always start with the biggest resolution you want to support and create your assets for that device - that usually means using the Retina display version of iPad. Then scale down your assets for the devices with the lower resolutions.

Scaling down from the Retina version of a device to non Retina display is simply scaling down by 0.5. Not much to think about here. This is why we are focusing on the cross device scalings.

You could do some direct scaling - e.g. from iPad5 to iPhone4 by resizing the 1536x2048 to 640x960 but with this you have 2 different scaling factors for x and y. This results in distorted shapes - circles become ellipses.

This might however be a solution for some background images - but not for foreground sprites and text. With iPhone5 the aspect ratio differences between the devices become more extreme - so it might not work anymore.

The scaling values listed here try to preserve with width or height. They result in additional pixels that have to be filled on one or the other device - or pixels hat are not visible.

It might also be an option to choose some values inbetween - dealing with additional and invisible pixels on a single device.

It's most important to always create the assets for the biggest resolution. This might lead to an unusual workflow: If your main design is for iPhone4 and you also want to support iPad3 you should create the assets for iPad and scale them down.

Continue reading...

Andreas Löw Join the Code'n'Web Newsletter (privacy policy)
I'm a robot