Blog Archives

Making 12 Games in One Year?!

About a week ago I signed up for One Game a Month, a challenge to make twelve games in 2013, roughly one per month. I already planned to release five new iPhone and iPad games on App Store in the first half of this year, so adding another seven isn’t such a big deal. :-)

This is a screenshot of the game I made for January, Galaxy Apocalypse:

Galaxy Apocalypse Screenshot

It’s a pretty simple game where you have to swipe planets into portals of the matching color before those portals run out of power and the whole galaxy explodes. You don’t want that to happen on your watch…

The game took five days to make from scratch to finish. If I had more time I would polish it more and put it on the App Store. In its current shape it’s not a bad game but still a bit below the level of what I think is good enough for the App Store, so I will clean up the source code (it’s quite messy right now) and put it on Github as a programming example.

Update: Here’s the code, github.com/hollance/GalaxyApocalypse

Here is a video of the game in action:

I have to say I like these sorts of challenges. I’ve done similar challenges in the past, such as composing at least one piece of piano music or coming up with at least one app idea each day for 30 days in a row. It’s a lot of work but it also pushes your creativity to higher levels.

When you limit yourself to making a game in a very short time, then by necessity you have to limit the scope of the game. Such constraints can be quite inspirational. How small can you make a game that is still interesting?

One of my most successful games, Ultimate Countdown (now removed from the App Store but coming back later this year in an all-new version), was done in a single weekend as a similar kind of challenge. It ended up being downloaded over 250,000 times, which I found quite impressive back in 2008, even for a free game.

So if you’re into game development — or if making games is something you’ve always dreamed of — then head on over to www.onegameamonth.com and sign up! Make games, not excuses. :-)

Transparent JPEG Images

When you distribute images with your app you usually pick the PNG or JPEG format. The advantage of JPEG is that it often compresses better — especially for photos — but unlike PNG it unfortunately does not support transparency.

The transparency in a PNG file comes from the so-called “alpha channel”. For every pixel not only red, green and blue values are stored but also an “alpha” value that determines how transparent that pixel is. A value of 255 means this pixel is fully opaque, 0 is fully transparent, and anything in between will mix the pixel’s RGB values with the underlying color.

This is probably an old trick, but by saving a JPEG image not as one but as two image files you can still have transparent images. The first image is the regular JPEG with as much compression as you can get away with, the second image is the alpha channel. This is a grayscale image with black representing fully transparent, white fully opaque, and gray everything in between.

 

Source image and its alpha channel
We can combine these two images at runtime to make the image transparent again. Because of the JPEG compression we lose a little bit of clarity but if you tweak the compression settings you can usually get away with it.

I wrote a simple category on UIImage that lets you do this.

Preparing your images

1) Export your image from Photoshop as a PNG with transparency.

2) Export the image again as a JPEG, using suitable compression settings. The background should have a solid color, typically white or black but any color will do.

3) Save the alpha channel to a separate JPEG or PNG image. I couldn’t find an easy way to do this from Photoshop, but the ImageMagick tool can do it without problems.

If you have ImageMagick installed, open a Terminal and go to the folder that contains the exported PNG image. Then type:

convert -alpha Extract -type optimize -strip -quality 60 +dither Source.png Alpha.jpg

This extracts the alpha channel from the PNG image and saves it as a JPEG file. You can tweak the level of compression with the -quality parameter. If you specify “Alpha.png” instead of “Alpha.jpg”, ImageMagick saves the alpha channel as a grayscale PNG-8 file. You should use whichever one makes the smallest file size.

Combining the images

1) Add the two JPEG images (the non-transparent source image and the alpha channel) to the app.

2) At some point, call the mh_combineWithAlphaImage:backgroundColor: method to combine these two images into a new, transparent, image.

3) Depending on your app you may want to do this only once and then store the transparent image as a PNG in your app’s Caches folder.

That’s it, quite easy.

Some notes

The alpha image does not have to be a JPEG, it can also be a PNG file. If it is a JPEG then it can have different quality/compression settings from the main image.

The current implementation works well but is not as fast as it could be. It also uses more memory than is strictly necessary. I might rewrite this at some point to use the Accelerate framework or Core Image.

Not all images compress better as JPEG. You should use JPEG only where it makes sense.

Check out the source code at Github.

Bird image by Sias van Schalkwyk

Making UIBarButtonItems in Photoshop

Recently I was working on an app that required brightly tinted tool bars and navigation bars:

A UIToolBar with a light blue tint color

As you can see, the light blue color makes the bar button hard to see and its label hard to read. Changing the background color of the button is really easy on iOS 5 because its UIBarButtonItem also has a .tintColor property. But if you still need to support iOS 4 then you’re out of luck.

In that case, the only solution is to put a UIButton inside the UIBarButtonItem and give it a background image that looks like a regular bar button. It’s a roundabout way of doing things but it works.

Previously, I would draw these bar button-lookalike images myself in Photoshop. By setting the appropriate layer styles on a rounded rectangle vector object you can make a decent approximation of what a real bar button item looks like.

This time, however, I wanted to take advantage of the actual images that UIKit itself uses to compose the UIBarButtonItem when you change the tintColor of the underlying toolbar or navigation bar.

To pull this off, you can download UIKit Artwork Extractor. Compile the app and run it on the Simulator (or on your device). It will extract all the images that are built into the various iPhone and iPad frameworks and save them to a folder on your computer.

After you have extracted the images, go into the “Shared” subfolder and look for:

  • UITintedButtonHighlight.png
  • UITintedButtonMask.png
  • UITintedButtonShadow.png

You can combine these three images with a fill color to produce a tinted UIBarButtonItem background image, like this:

How to add the different images to produce the final bar button image

The actual layers pane should look like this:

The Layers pane in Photoshop

The “Fill color” layer is simply a rectangle filled with the tint color that you want the button to have. As you can see, both the fill layer and the “shadow” layer are clipped against the red “mask” layer. If you don’t do that, the button won’t have a transparent background in the corners.

To export the image, merge all the visible layers (but not the background!) and save the image as PNG. This gives you a 11×30 pixels stretchable image.

You can use the following category to create the fake bar button items in your code. It requires that the image named “BarButton.png” is added to your project.

@implementation UIBarButtonItem (FakeButtons)
 
- (id)initWithTitle:(NSString *)title width:(CGFloat)width target:(id)target action:(SEL)action
{
	UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
	[button setTitle:title forState:UIControlStateNormal];
	[button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
	button.titleLabel.font = [UIFont boldSystemFontOfSize:12];
	button.titleLabel.shadowColor = [UIColor colorWithWhite:0 alpha:0.5];
	button.titleLabel.shadowOffset = CGSizeMake(0, -1);
	button.frame = CGRectMake(0, 0, width, 30);
 
	UIImage *image = [[UIImage imageNamed:@"BarButton"] stretchableImageWithLeftCapWidth:5 topCapHeight:0];
	[button setBackgroundImage:image forState:UIControlStateNormal];
 
	return (self = [self initWithCustomView:button]);
}
 
@end

In the “Shared” folder you will also find images for the UINavigationController back button (named UITintedBackButtonXXX.png), but be advised that bar button items with a custom view won’t work on UINavigationItem’s backBarButtonItem property. You’ll have to put your custom back button on leftBarButtonItem instead.

Tip: If you also want to have Retina-sized images, run Artwork Extractor on a Retina device or on the Simulator in Retina mode. It’s very enlightening to look through the rest of the extracted artwork as well.

Good Software

Good Software…

Is instantaneous, it doesn’t make me wait.

Remembers things for me.

Draws intelligent conclusions based on my past behavior and correctly predicts what I want to do next.

Allows me to make mistakes and experiment.

Is predictable, it should not confuse me by doing something I did not expect.

Is dependable, it does not lose or corrupt my data.

Is polite, it doesn’t interrupt me.

Gets out of my way.

Puts my needs first, not those of the computer or the developer (or publisher/brand/investor/sponsor).

Is an extension of me, not another burden to carry.

Makes my life easier, not more frustrating.

Is smart, it does not require me to hold its hand all the time.

Should shape itself to my perception of reality.

(We have a long way to go still!)

Just Say No to Splash Screens

The client briefs that I receive often contain the requirement that “the app should display our logo when it starts”. In other words, a splash screen. Unless you’re making a game, I think adding a splash screen to your app is a bad idea, and here is why:

Splash screens make your app appear to start up slower. When the user launches an app, he expects to be able to interact with it immediately. If you show a splash screen first, he has to make a context switch from what he expected to see (the actual app) to your logo and back again when the app is done loading and its real interface finally appears.

Instead, if you do what Apple recommends in the HIG—show an empty version of your UI, without any content—then the perceived app startup time is actually shorter and users are happier as a result. Anything you can do to make your users happier is something you should do.

All iPhone and iPad apps contain a launch image, Default.png, that is shown when the app is being loaded by the operating system. Unfortunately the temptation is big to put a logo in this image. Don’t, as that is not what it’s there for.

Here is the launch image of an app I recently completed for a client. Boring, but effective.

A typical Default.png launch image
Splash screens are about you, not about the user. You probably like your logo very much and I’m sure it is pretty, but here is something you need to realize: the user doesn’t particularly care about you or your logo. You, on the other hand, should care very much about the user.

Most people just want to get on with things and if your app helps them do so, great! But if the app gets in their way, it only takes three taps to uninstall.

If your app is a novelty app designed to promote your brand, then remember that unless the app delivers some kind of value, people won’t be using it for very long and they won’t get much exposure to your message. Focus on the value, not on the brand.

Forego the splash screen and find a better way to integrate your branding in the app’s user interface. Give people a good experience to associate with your brand, rather than shoving it into their faces.

The launch image is rarely shown anymore. Now that almost everyone has OS 4 with multitasking on their iPhone, apps resume where they left off the next time they are opened. This means the load image, i.e. your splash screen, is only shown for a brief instant the very first time the app is used.

The launch image also appears if your app is re-launched after it was truly terminated, which occasionally happens when there is not enough free memory to keep all suspended apps around. Most of the time, however, when the app loads the user sees a snapshot of where he last left off.

Showing your splash screen only now and then makes for a very inconsistent experience. Putting a logo in the launch image might have worked on the slower models when there was no multitasking yet, but no more.

Don’t get too clever! If your app launches really quickly—and it should!—then the load image is only visible for a second or so, especially on the fast iPhone 4. Hardly long enough to make an impression.

To “solve” this problem, some apps use a timer that keeps the splash screen visible for a few seconds more before it fades into the main interface. How silly is that? You are not doing the user any favors by purposely slowing down the launching of the app.

Let me say it again: the app is not about you, your brand or your logo, it is about the user and the goal he wants to accomplish.

If your app is a game, then it makes sense to show a “Loading…” screen but for any other apps, do the right thing and put a blank version of your UI in the default load image.