Escaping the egg: Sparrow 1.2!

Daniel Sperl on May 25, 2011

Summer is coming up in its natural habitat - thus, our little bird has prepared itself for its favorite season. It grew lots of shiny new feathers, brushed some dirt off its coat, and is launching into a high and joyful flight: in other words, Sparrow 1.2 is here!

A quick note before you upgrade

When you download and install the new version, your projects won't compile right away. The problems are quick to fix, though. You only have to make the following two small changes:

  • Sparrow requires an additional library: zlib. Under "Build Phases" - "Link Binary with Libraries" (Xcode4) or "Target Info" - "General" - "Linked Libraries" (Xcode3), you have to add the following library: libz.dylib
  • We had to change the name of one method, because it caused problems in certain environments. Thus, you have to change your calls to[SPUtils randomIntBetween:and:] to this: [SPUtils randomIntBetweenMin:andMax:]

Now, let's have a look at the new version. Besides adding new features, we took the time to fix a lot of small bugs that had popped up during the last months. We got rid of every single bug that was reported in the forum. Thus, this version of Sparrow is for sure the most solid and stable release ever - and I think we set the bar quite high in our previous releases, already! This alone should be a good reason to upgrade. The new features are just the icing on the cake, right?

Pivot Points

I think this was one of the very first requests we ever received for Sparrow: the possibility to move the pivot point (or origin, root, anchor - whatever you'd like to call it) to a custom location. This is especially useful when you want to rotate an image around its center. Until now, you had to move the object to a container sprite to be able to do that:

SPImage *image = [SPImage imageWithContentsOfFile:@"texture.png"];

SPSprite *sprite = [SPSprite sprite];
image.x = -image.width / 2.0f;
image.y = -image.height / 2.0f;
[sprite addChild:image];

sprite.rotation = SP_D2R(45.0f); // -> rotate around center

Not a big deal, Flash users do that all the time (that's why I hesitated adding this feature in the first place). But I admit that it's a lot of code for such a simple thing. That's why I finally gave in! Here's how you do the same in Sparrow 1.2:

SPImage *image = [SPImage imageWithContentsOfFile:@"texture.png"];
image.pivotX = image.width / 2.0f;
image.pivotY = image.height / 2.0f;
image.rotation = SP_D2R(45.0f); // -> rotate around center

No more container sprite needed! To stick with the analogy I use in the documentation: the pivot point defines the position where you stab the pin through the object when you attach it to its parent. The code above moves the pivot point to the center of the object.

Thanks to Shilo White for his origin point implementation, which finally pushed me to add that feature to Sparrow.

Enhanced Texture Options

Especially users of the Texture Packer will be happy about the following features:

Texture Frames aka Trimmed Textures

Some textures have a transparent area around them for one reason or the other. Especially the textures of an SPMovieClip tend to be that way. This takes up precious texture memory.

Now you can trim that transparent region away and have the texture still act just like before (i.e. reporting the same size as before). This is done with the new frame property of SPTexture - but don't bother about the details, just mark the "Trim" checkbox in TexturePacker.

Unfortunately, Sparrow's texture atlas generator does not yet support that feature because of several bugs in the latest version of ImageMagick, but it will be updated when those problems are resolved.

Support for Gzip'ed PVR textures

As some of you might know, the PVR texture format comes in two forms: compressed (PVRTC) and uncompressed (PVR). While the compressed format takes up very little space, it can have a negative impact on the image quality. The uncompressed version supports 16 bit image formats (compared to the 32 bit of PNG), but files with that format take up a lot of disk space.

The downside of the uncompressed PVR textures (the large file size) is now taken care of by being able to compress them with the GZip algorithm. A texture in that format just has to have the extension .pvr.gz for Sparrow to recognize it. This is a great alternative when your 32 bit PNGs take up too much space and the compressed PVR textures are too ugly.

Confused? Don't worry, I will write a blog entry with more information on that topic, so come back soon for more information.

Adjustable Texture Filtering

When you display a texture in a scaled way (making it bigger or smaller), the graphics chip has to calculate how the pixels of the texture appear on the screen. How this is done depends on the filter algorithm, and this has been a fixed setting in Sparrow until now.

With Sparrow 1.2, you can customize the texture filtering method. The image below shows you the options. "Nearest Neighbor" is useful when you create retro-style games with low resolutions, or whenever you need sharp borders. "Bilinear Filtering" is the default: it looks good, and renders just as fast as "Nearest Neighbor", thanks to the iPhone's GPU. "Trilinear Filtering" looks even better - you won't notice it in the screenshot, but you can see the difference when you animate a change in scale of an image. Use the latter with care, it is somewhat slower on older hardware.

The setting is modified with the new filter-property of SPTexture.

Kerning for Bitmap fonts

Bitmap fonts now use the Kerning information provided by Glyph Designer and Bitmap Font Generator. That means that rendered text will be noticeably more beautiful than before, when the font supports it.

Thanks to Ludometrics for the base code for that feature!

Shortcuts for often-needed calls

Accessing stage and stage-juggler

As a Sparrow-user, you might have come across the following issue: you want to access the stage juggler like this:

- (id)init
  if ((self = [super init]))
    SPJuggler *juggler = self.stage.juggler;
    // ...

But the juggler is nil. That's because the object you are initializing is not yet connected to the stage (can't be), and thus self.stage just returns nil. Bummer.

Now there is an alternative that allows you to access the stage (and thus, the juggler) anywhere, anytime.

SPStage *stage = [SPStage mainStage];
SPJuggler *juggler = [stage juggler];

The method [SPStage mainStage] returns the first stage in existence. If you're like me, you'll have only one stage per game anyway - so nothing will blow up behind you because of this little trick.

Rotating or moving an object

When you want to scale an object with a tween, it is likely that you want to scale it uniformly, setting scaleX and scaleY to the same value. And when you move an object, you need to change both the x- and y-coordinates. In Sparrow 1.2, there are two nice little shortcuts for those operations.

SPTween *tween = [SPTween tweenWithTarget:anObject time:5.0];
[tween scaleTo:2.0f];
[tween moveToX:20.0f y:40.0f];

// that is equivalent to:
[tween animateProperty:@"scaleX" targetValue:2.0f];
[tween animateProperty:@"scaleY" targetValue:2.0f];
[tween animateProperty:@"x" targetValue:20.0f];
[tween animateProperty:@"y" targetValue:40.0f];

Want more?

These are the most notable additions, but there are more! Find the complete list of changes and bugfixes in the changelog.

During the last days, the latest version was already heavily tested by several forum users (thanks!), and no problems have arisen so far. Thus, there's no reason to wait - upgrade now! As always, I am happy about any feedback, and should you encounter any problems, please post a description of the problem in the forum - we will help you out as quickly as possible.

Special thanks to

  • Shilo White for the Pivot Point
  • Ludometrics for Bitmap Font kerning
  • Tadas Vilkeliskis for tweening of unsigned integers
  • Jonathan Shieh for his fix that allows unit tests to load files
  • Andreas Wålm for making generate_atlas.rb work with ruby 1.9
  • numerous forum members for bug reports, suggestions and feedback!