- January 2006 (1)
- January 2007 (1)
- July 2007 (8)
- August 2007 (3)
- September 2007 (3)
- October 2007 (2)
- November 2007 (3)
- January 2008 (5)
- February 2008 (4)
- March 2008 (1)
- April 2008 (5)
- June 2008 (3)
- July 2008 (2)
- August 2008 (1)
- September 2008 (6)
- November 2008 (3)
- December 2008 (1)
- January 2009 (4)
- March 2009 (1)
- April 2009 (14)
- May 2009 (9)
- June 2009 (7)
- July 2009 (6)
- August 2009 (4)
- September 2009 (4)
- October 2009 (2)
- November 2009 (23)
- December 2009 (23)
- January 2010 (4)
- February 2010 (3)
- March 2010 (2)
- May 2010 (3)
- July 2010 (4)
Core Animation Performance Tips
In my copious free time, I've been working on a videogame for the iPad. Friends and family may interject here that it seems like I'm always working on a videogame in my free time, but I've never actually finished one. This time is different. Really.
All of my personal projects are intended primarily to be interesting and fun for me. I gave myself a couple of technical constraints to keep things challenging:
- All the code is well-factored idiomatic Objective-C. Unlike a lot of iPhone/iPad game programmers, I'm not writing all the guts in low-level C or C++ and then sprinkling a minimal amount of Cocoa on top to interface with the OS.
- I'm using Core Animation as my "engine", rather than the OpenGL ES API or an off-the-shelf gaming engine. (Note: My game only needs a couple dozen sprites.)
So far, things have worked out well. I was worried that using Objective-C and Core Animation might lead to performance issues on the iPad, but that hasn't been the case. I have run into a couple of issues with Core Animation that were pretty easy to fix.
Layer Creation Is Expensive
My game's "sprites" are just Core Animation layers. When I initially implemented the game, I was creating layers and adding them to the view as needed, and then deleting them when they were no longer needed. This turned out to cause problems; a few frames would get dropped whenever a layer was created.
The fix for this was to create a pool of layers and add them all to the view at startup, and reuse those layers as needed. Unused layers get their hidden property set false.
Watch Out for Misaligned Images
If you run an app with Instruments with the Core Animation tool, it has an option to highlight "misaligned images." I couldn't find a lot of information on this, but apparently if you give layers positions that are not perfectly aligned to pixels, Core Animation does some anti-aliasing when rendering those layers, which degrades performance.
The easy fix is to just round all positions to whole pixels, via something like this:
- (void) setSpritePosition:(CGPoint)position {
CGPoint alignedPosition;
alignedPosition.x = floorf(0.5f + position.x);
alignedPosition.y = floorf(0.5f + position.y);
sprite.position = alignedPosition;
}
This got rid of most of my misaligned images, but I do still have some sprites that get rotated or scaled via a transform, and such images are always misaligned, unless they are rotated by some multiple of 90 degrees. Thankfully, I only have a few such sprites.