I create the UITextField like normal:
txtName = [[UITextField alloc] initWithFrame: CGRectMake(160, 240, 200, 32)];
I add it to the subview like so:
[[[CCDirector sharedDirector] openGLView] addSubview: txtName];
The problem I'm having is that, when I change the orientation to PortraitUpsideDown with this command:
[[CCDirector sharedDirector] setDeviceOrientation:CCDeviceOrientationPortraitUpsideDown];
the UITextField and the keyboard don't change with the new orientation. When I click on the text box, the keyboard appears upside down and on the top of the screen.
I know I can change the rotation of the UITextField using CGAffineTransformMakeRotation, but how do I make the keyboard appear upright and at the bottom of the screen when in PortraitUpsideDown orientation?
When I detect an orientation change, in addition to setting the Director's device orientation like so:
[[CCDirector sharedDirector] setDeviceOrientation:CCDeviceOrientationPortraitUpsideDown];
I also needed to set the UIApplication's StatusBarOrientation as well
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortraitUpsideDown];
This caused the keyboard to orient and position itself correctly.
Hope this helps someone!
iPhone Top Tips is for developers who are working on iPhone Application Development or Games Development. I post here my past experience and new techniques which will useful for you guys.
Monday, October 25, 2010
Friday, October 22, 2010
Mac App Store Coming Soon - Port your cocs2d game for Mac
Apple to announce that in 90 days Mac App Store will be ready.
The Mac App Store will be similar to the App Store, but instead of distributing iOS applications, it will distribute Mac applications.
This is big news for cocos2d users, since cocos2d already supports Mac!!
The guidelines and other requirements for the Mac App Store are online:
* Mac App Store Review Guidelines
* App Store Resource Center
So, download the latest cocos2d version, and start porting your cocos2d game for Mac!
The Mac App Store will be similar to the App Store, but instead of distributing iOS applications, it will distribute Mac applications.
This is big news for cocos2d users, since cocos2d already supports Mac!!
The guidelines and other requirements for the Mac App Store are online:
* Mac App Store Review Guidelines
* App Store Resource Center
So, download the latest cocos2d version, and start porting your cocos2d game for Mac!
Wednesday, October 20, 2010
Cocos2d Game Development Performance Tips
Cocos2d for iPhone is a wonderful open source framework that makes it easy to draw 2D graphics with OpenGL ES. It allows to you unlock the power of the graphics hardware in iPhone OS devices, without having to deal with all the details of working with GL. Having said that, using Cocos2d is a great way to get your feet wet with GL programming. I’d never done any OpenGL stuff before, but I found I picked up quite a bit as I went along. It handles most of the hard stuff, but it’s very easy to subclass and handle drawing yourself as you become more experienced.
When I started working on the bizarre experiment that eventually became Space Harvest, I initially used Core Animation. This is great, up to a point, but I found I soon hit a performance wall - Core Animation wasn’t flexible enough to handle the types of things I wanted to do, and doesn’t really give you a lot of control over what’s happening under the hood.
Once I switched to Cocos2d, I found that a) it was a lot easier to get something that ran relatively smoothly, and b) because it’s designed for games, it provides loads of functionality to make your life easier.
This post is about some of the things I learned about improving performance when using Cocos2d. A lot of the time, I found out about this stuff by doing it the wrong way to start with. Though I doubt they’ll be anything here for experienced game developers, I hope my tips may be useful to anyone who (like me) is quite new to OpenGL and game development.
Profiling with Instruments
As with any software, before you start doing any work to improve performance, you should first look for where the bottlenecks are.
Run your project with the CPU sampler instrument to see where your program is spending its time. Though you can sometimes get valuable results by profiling on the simulator, you should try to do as much profiling on the device as possible. You probably already know the device usually runs software much slower than the simulator, but this is even more obvious with CPU/GPU intensive software like games. The device is MUCH slower at certain things than the simulator, so the only real way of seeing where the actual performance bottlenecks lie is to run on the device.
I find the most helpful way to start looking for potential performance bottlenecks is:
* Change Sample Perspective to ‘Running sample times’
* Change Active Thread to ‘Main Thread’. 99% of the time, the performance intensive parts of your game will be single threaded (on a single core device like the iPhone / iPod touch, it wouldn’t really make sense to do it any other way)
* Turn off invert call tree, and expand the list until you find [CCDirector mainLoop]
They’ll probably be two main places where your application will be spending its time - drawing, and running your main loop for game logic.
Always look for the low hanging fruit - those parts of your code that are taking up lots of time, and can be easily optimised. If your game is spending any significant amount of time in [CCScheduler tick], you should start your optimisation work there. Optimising your game logic will usually be less painful than optimising your drawing.
Testing on different devices
For most iPhone OS applications, the differences in hardware between devices is not particularly significant. Users might notice that things are a little more snappy on newer devices like the 3GS newer iPod Touches, but generally, it isn’t a big deal.
For games, the performance gap between the older devices and the newer ones is HUGE.
In Space Harvest, each level has a loading screen because it can take a while to pre-load the textures and load the maps that make up the game world. I thought it would be nice to include tips on how to play on the loading screen so users weren’t actually staring at nothing while each level loaded.
I performed the majority of my testing on my 3G iPhone. During the last couple of weeks before I released the first version of Space Harvest, I got to test Space Harvest on a 3GS iPhone. The first thing I noticed was that I could no longer read the tips. What might have been a ten second wait for loading on the 3G became a barely noticeable blue flash on screen before the level started on the 3GS. I ended up introducing a ‘tap to continue’ message, just to let people with newer devices see the playing tips.
So, the newer devices are faster - not just a bit faster, but a lot faster. A lot faster at loading textures, a lot faster at drawing things with OpenGL, a lot faster at just about everything. If you aren’t testing on older devices, how will you know if your game is even playable on older devices?
Ignoring the iPad for now, in performance terms, there are three classes of iPhone OS device:
* Slowest devices: iPhone / iPhone 3G / 1st gen iPod Touch(i)
* 2nd gen iPod Touch, 3rd gen iPod touch 8GB
* Fastest devices: iPhone 3GS, 32GB / 64GB 3rd gen iPod Touch
A couple of other random notes about the differences between older and newer devices:
* Older devices have half the RAM of newer devices (128MB vs 256MB), which means the likelihood of low memory warnings is much greater. This makes it even more important to manage your memory carefully.
* Older devices only support textures up to a maximum of 1024x1024 pixels. You should avoid textures larger than this size if you want your game to work on older phones and iPods.
Textures and Texture Atlases
Loading textures on the device is rather slow. Because of this, you should try to load textures before the user starts playing a level that may need them, otherwise you might get hiccups in frame rate.
When you create a sprite in Cocos2d, you’ll normally pass in a reference to the texture you want it to use, eg:
CCTexture2D *texture =
[[CCTextureCache sharedTextureCache] addImage:@"mytexture.png"];
CCSprite *sprite = [CCSprite spriteWithTexture:texture];
This helps keep things nice and simple. However, if you’re loading all your textures in advance, you may notice that loading starts to slow down on older devices - the more textures you load, the slower it gets.
Speeding up loading times
At one point during the development of Space Harvest, loading textures was taking more than 20 seconds. Just for loading textures. Once textures were loaded, the user would still have to wait for the map to load. Ouch!
The reason for this was that I hadn’t paid attention to what everyone was saying, and I wasn’t using texture atlases.
A texture atlas is basically a large image that contains lots of smaller textures. On the right is an example of one of the texture atlases used in Space Harvest.
Using a texture atlas can help speed up drawing significantly (more on this below), but equally importantly, it helps speed up texture loading, and helps reduce the amount of memory your textures will use once loaded.
Space Harvest uses lots of different sprites, some with as many as 50 frames of animation. By combining 50 textures into one texture, you’ll cut loading texture loading times significantly.
The newest versions of Cocos2d make this pretty easy. Here, we’re creating a sprite using a rectangular portion (specified in pixels) of a larger texture:
CCTexture2D *texture =
[[CCTextureCache sharedTextureCache] addImage:@"myatlastexture.png"];
CCSprite *sprite =
[CCSprite spriteWithTexture:texture rect:CGRectMake(0,0,32,32)];
Reducing memory usage
I mentioned you can also save memory by using atlas textures. This is because textures in Open GL ES must have a width and height that are a power of two, eg 64x128, 256x1024, 512x512 etc.
Cocos2d is smart enough to resize your images for you when it comes to loading textures, but look at all the space we’re wasting! In the above example, our 144x93 texture became a 256x128 texture once it got loaded into memory. This means we’ve ended up with more wasted space in our texture than used space!
For a single texture, this won’t be a big deal, but what happens when we load 50 textures like this? 50 times as much waste. Again, using texture atlases is a great way to solve this problem - you can easily combine lots of textures that don’t have a power of two width and height into a single texture that does.
Flipping textures
Another tip to cut down on memory usage is to use flipped textures. If your sprite looks the same when drawn facing in the opposite direction (but just horizontally or vertically flipped), you can use the same texture, and do the flipping in code by setting the flipX / flipY properties of your sprite.
Pixel formats
Cocos2d provides several different pixel formats for loading your textures. These are quite distinct from the format you use to save your texture images.
When saving a PNG image in Photoshop, I can decide whether I want to save it as an 8-bit indexed colour image, or a 24-bit truecolor image, or a 32-bit image that includes an alpha channel. The format I choose will depend on the nature of the image. 8-bit PNG is best suited for images with few colours that don’t use partial transparency. 32-bit images can have many colours and include partial transparency, though the file size will often be significantly larger.
When loading textures, the original format of the image doesn’t really matter that much - what’s important is the pixel format we use for loading. As with saving images for the web, it’s basically a question of balancing image quality and size.
kTexture2DPixelFormat_RGBA8888 is the default pixel format for textures, and provides the best image quality. It uses 8 bits for each colour (Red, Green and Blue), plus 8 bits for the alpha channel, for a total of 32 bits per pixel.
kTexture2DPixelFormat_RGBA4444 will use only 4 bits for each colour, plus 4 bits for the alpha channel, for a total of 16 bits per pixel. A texture stored in memory in this format will use half the size of one loaded with kTexture2DPixelFormat_RGBA8888.
For larger textures like atlases, this difference is very important. A 1024x1024 texture will use 4MB of texture memory when loaded with RGBA8888, but only 2MB of texture memory when loaded with RGBA4444!
Try to avoid using RGBA8888 unless you absolutely need the best possible quality for a particular texture. A lot of the time, you won’t even notice the difference between RGBA8888 and one of the other pixel formats. Gradients are a good example of where RGBA8888 is most useful:
To cut down on the number of times you have to set the pixel format, set it to the format you’re likely to use most often when your game starts:
[CCTexture2D setDefaultAlphaPixelFormat:kTexture2DPixelFormat_RGBA4444];
Then, whenever you need to change the pixel format for loading a particular texture, make sure you change it back afterwards:
[CCTexture2D setDefaultAlphaPixelFormat:kTexture2DPixelFormat_RGBA8888];
CCTexture2D *texture =
[[CCTextureCache sharedTextureCache] addImage:@"buttonsatlas.png"];
[texture setAliasTexParameters];
[CCTexture2D setDefaultAlphaPixelFormat:kTexture2DPixelFormat_RGBA4444];
Considering the pixel format you’ll end up using is important when planning your texture atlases. As each loaded atlas can only have one pixel format, you should try to ensure that you keep textures that require RGBA8888 together the same atlases, so you only have to use that pixel format for those textures.
A guide to the different pixel formats Cocos2d uses for textures, including hints on when to use each, appears here.
PVRTC
PVRTC is a special texture format you can use on iPhone OS devices. PVRTC textures take up less texture memory than regular textures of the same size, and can be drawn faster.
You can generate PVRTC textures from regular images using the texturetool program that comes with the Developer tools.
While PVRTC textures have some advantages, they also have one big disadvantage - compression artifacts.
The above image is probably showing the worst-case scenario - the kind of images for which PVRTC is least well suited. Space Harvest is a 2D game, so you’re basically always looking at the textures head on. Additionally, because the visual style of Space Harvest relies on crisp, non-antialiased graphics, artifacts are that much more visible.
In fact, PVRTC textures can be very useful, even in 2D games. For more detailed, anti-aliased sprites, or photorealistic textures, you might not even notice the difference. Space Harvest uses PVRTC for background images. But wherever clarity is very important, you should probably avoid them.
CCSpriteSheet
CCSpriteSheet is one way to unlock big performance improvements when drawing. Each sprite sheet has a texture atlas. When we create a sprite that uses that texture atlas, we can chose to attach our sprite to the sprite sheet by adding it as a child of the sprite sheet.
Why do this? Well, our sprite sheet will take over the drawing of our sprite. Rather than drawing each sprite individually, it will draw all sprites attached to that sprite sheet at once. This matters because one of the best ways to improve performance in an Open GL application is to cut down on the number of GL calls your code makes. Cocos2d handles most of the Open GL stuff for you, but it is helpful to have an understanding of what it’s doing behind the scenes.
Here is part of the draw method for CCSprite:
BOOL newBlend = NO;
if( blendFunc_.src != CC_BLEND_SRC || blendFunc_.dst != CC_BLEND_DST ) {
newBlend = YES;
glBlendFunc( blendFunc_.src, blendFunc_.dst );
}
#define kQuadSize sizeof(quad_.bl)
glBindTexture(GL_TEXTURE_2D, [texture_ name]);
int offset = (int)&quad_;
// vertex
int diff = offsetof( ccV3F_C4B_T2F, vertices);
glVertexPointer(3, GL_FLOAT, kQuadSize, (void*) (offset + diff) );
// color
diff = offsetof( ccV3F_C4B_T2F, colors);
glColorPointer(4, GL_UNSIGNED_BYTE, kQuadSize, (void*)(offset + diff));
// tex coords
diff = offsetof( ccV3F_C4B_T2F, texCoords);
glTexCoordPointer(2, GL_FLOAT, kQuadSize, (void*)(offset + diff));
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
if( newBlend )
glBlendFunc(CC_BLEND_SRC, CC_BLEND_DST);
(Emphasis mine, obviously)
Look at the number of calls to functions that begin with ‘gl’ - 7 calls in the worst case. This code will run every time we draw a sprite that isn’t attached to a sprite sheet. If we have 100 sprites, 700 calls, or 7000 gl calls for 1000 sprites.
CCSpriteSheet’s draw method is a bit more complex, and calls a separate method on it’s texture atlas to do the drawing. For brevity, I won’t repeat it here, but it looks like it makes around 10 gl calls. But crucially, it will only make those 10 calls to draw ALL of the sprites attached to our sprite sheet - 100 sprites will be 10 calls, even with 1000 sprites, it’ll still be 10 calls. In practice, this gives you a huge boost in drawing performance.
A note about depth sorting and CCSpriteSheet
If you need to depth-sort sprites from one atlas with sprites from another, things get a bit more complex.
By default, Cocos2d renders graphics using the Painter’s Algorithm. That means that objects are drawn in the order in which they appear in their parent node’s children array. The end result is that objects at the back are drawn first, objects that appear on top of everything else are drawn last.
This presents a problem if you need some objects attached to a particular sprite sheet to be drawn in front of those from another sprite sheet, but behind others from that same sprite sheet. By default, once the sprites from the first atlas have been drawn, the sprites from the second atlas will draw over the top of them, regardless of their z position relative to their siblings.
The way around this is to use CCNode’s vertexZ property. This gives you access to Open GL’s depth buffer, which allows you to draw your sprites in any order you like, and still allow them to be correctly depth sorted in relation to one another.
The biggest downside to this approach is that it can be difficult to get semi-transparent sprites to render properly, as the object directly behind them may not have been drawn when they come to be rendered. Apple’s advice is to draw semi-transparent objects last, which in practice means you’ll need to keep their sprite sheet in a higher position in its parent’s children array.
I didn't use vertexZ for depth sorting in Space Harvest - from the couple of days I spent experimenting with it, I found lots of little side effects that made it tricky to get things working the way I wanted. Regardless, try to use CCSpriteSheet as much as you can.
Pre-render programatically generated textures if you can
Some of the effects in Space Harvest are programatically generated using Core Graphics. Many objects have animations for taking damage and being destroyed - these are created by combining different images using different blending modes:
Originally, I generated textures for destroy animations for all my sprites when starting the game. However, Core Graphics is rather slow on the iPhone platform, so I eventually moved to saving the generated images out, pasting them into to my atlases in Photoshop, and loading them as regular textures in the final version. This cut around 10 seconds(!) off startup time, so if you do have any programatically generated textures that don't change, pre-rendering them is a good way to go.
When I started working on the bizarre experiment that eventually became Space Harvest, I initially used Core Animation. This is great, up to a point, but I found I soon hit a performance wall - Core Animation wasn’t flexible enough to handle the types of things I wanted to do, and doesn’t really give you a lot of control over what’s happening under the hood.
Once I switched to Cocos2d, I found that a) it was a lot easier to get something that ran relatively smoothly, and b) because it’s designed for games, it provides loads of functionality to make your life easier.
This post is about some of the things I learned about improving performance when using Cocos2d. A lot of the time, I found out about this stuff by doing it the wrong way to start with. Though I doubt they’ll be anything here for experienced game developers, I hope my tips may be useful to anyone who (like me) is quite new to OpenGL and game development.
Profiling with Instruments
As with any software, before you start doing any work to improve performance, you should first look for where the bottlenecks are.
Run your project with the CPU sampler instrument to see where your program is spending its time. Though you can sometimes get valuable results by profiling on the simulator, you should try to do as much profiling on the device as possible. You probably already know the device usually runs software much slower than the simulator, but this is even more obvious with CPU/GPU intensive software like games. The device is MUCH slower at certain things than the simulator, so the only real way of seeing where the actual performance bottlenecks lie is to run on the device.
I find the most helpful way to start looking for potential performance bottlenecks is:
* Change Sample Perspective to ‘Running sample times’
* Change Active Thread to ‘Main Thread’. 99% of the time, the performance intensive parts of your game will be single threaded (on a single core device like the iPhone / iPod touch, it wouldn’t really make sense to do it any other way)
* Turn off invert call tree, and expand the list until you find [CCDirector mainLoop]
They’ll probably be two main places where your application will be spending its time - drawing, and running your main loop for game logic.
Always look for the low hanging fruit - those parts of your code that are taking up lots of time, and can be easily optimised. If your game is spending any significant amount of time in [CCScheduler tick], you should start your optimisation work there. Optimising your game logic will usually be less painful than optimising your drawing.
Testing on different devices
For most iPhone OS applications, the differences in hardware between devices is not particularly significant. Users might notice that things are a little more snappy on newer devices like the 3GS newer iPod Touches, but generally, it isn’t a big deal.
For games, the performance gap between the older devices and the newer ones is HUGE.
In Space Harvest, each level has a loading screen because it can take a while to pre-load the textures and load the maps that make up the game world. I thought it would be nice to include tips on how to play on the loading screen so users weren’t actually staring at nothing while each level loaded.
I performed the majority of my testing on my 3G iPhone. During the last couple of weeks before I released the first version of Space Harvest, I got to test Space Harvest on a 3GS iPhone. The first thing I noticed was that I could no longer read the tips. What might have been a ten second wait for loading on the 3G became a barely noticeable blue flash on screen before the level started on the 3GS. I ended up introducing a ‘tap to continue’ message, just to let people with newer devices see the playing tips.
So, the newer devices are faster - not just a bit faster, but a lot faster. A lot faster at loading textures, a lot faster at drawing things with OpenGL, a lot faster at just about everything. If you aren’t testing on older devices, how will you know if your game is even playable on older devices?
Ignoring the iPad for now, in performance terms, there are three classes of iPhone OS device:
* Slowest devices: iPhone / iPhone 3G / 1st gen iPod Touch(i)
* 2nd gen iPod Touch, 3rd gen iPod touch 8GB
* Fastest devices: iPhone 3GS, 32GB / 64GB 3rd gen iPod Touch
A couple of other random notes about the differences between older and newer devices:
* Older devices have half the RAM of newer devices (128MB vs 256MB), which means the likelihood of low memory warnings is much greater. This makes it even more important to manage your memory carefully.
* Older devices only support textures up to a maximum of 1024x1024 pixels. You should avoid textures larger than this size if you want your game to work on older phones and iPods.
Textures and Texture Atlases
Loading textures on the device is rather slow. Because of this, you should try to load textures before the user starts playing a level that may need them, otherwise you might get hiccups in frame rate.
When you create a sprite in Cocos2d, you’ll normally pass in a reference to the texture you want it to use, eg:
CCTexture2D *texture =
[[CCTextureCache sharedTextureCache] addImage:@"mytexture.png"];
CCSprite *sprite = [CCSprite spriteWithTexture:texture];
This helps keep things nice and simple. However, if you’re loading all your textures in advance, you may notice that loading starts to slow down on older devices - the more textures you load, the slower it gets.
Speeding up loading times
At one point during the development of Space Harvest, loading textures was taking more than 20 seconds. Just for loading textures. Once textures were loaded, the user would still have to wait for the map to load. Ouch!
The reason for this was that I hadn’t paid attention to what everyone was saying, and I wasn’t using texture atlases.
A texture atlas is basically a large image that contains lots of smaller textures. On the right is an example of one of the texture atlases used in Space Harvest.
Using a texture atlas can help speed up drawing significantly (more on this below), but equally importantly, it helps speed up texture loading, and helps reduce the amount of memory your textures will use once loaded.
Space Harvest uses lots of different sprites, some with as many as 50 frames of animation. By combining 50 textures into one texture, you’ll cut loading texture loading times significantly.
The newest versions of Cocos2d make this pretty easy. Here, we’re creating a sprite using a rectangular portion (specified in pixels) of a larger texture:
CCTexture2D *texture =
[[CCTextureCache sharedTextureCache] addImage:@"myatlastexture.png"];
CCSprite *sprite =
[CCSprite spriteWithTexture:texture rect:CGRectMake(0,0,32,32)];
Reducing memory usage
I mentioned you can also save memory by using atlas textures. This is because textures in Open GL ES must have a width and height that are a power of two, eg 64x128, 256x1024, 512x512 etc.
Cocos2d is smart enough to resize your images for you when it comes to loading textures, but look at all the space we’re wasting! In the above example, our 144x93 texture became a 256x128 texture once it got loaded into memory. This means we’ve ended up with more wasted space in our texture than used space!
For a single texture, this won’t be a big deal, but what happens when we load 50 textures like this? 50 times as much waste. Again, using texture atlases is a great way to solve this problem - you can easily combine lots of textures that don’t have a power of two width and height into a single texture that does.
Flipping textures
Another tip to cut down on memory usage is to use flipped textures. If your sprite looks the same when drawn facing in the opposite direction (but just horizontally or vertically flipped), you can use the same texture, and do the flipping in code by setting the flipX / flipY properties of your sprite.
Pixel formats
Cocos2d provides several different pixel formats for loading your textures. These are quite distinct from the format you use to save your texture images.
When saving a PNG image in Photoshop, I can decide whether I want to save it as an 8-bit indexed colour image, or a 24-bit truecolor image, or a 32-bit image that includes an alpha channel. The format I choose will depend on the nature of the image. 8-bit PNG is best suited for images with few colours that don’t use partial transparency. 32-bit images can have many colours and include partial transparency, though the file size will often be significantly larger.
When loading textures, the original format of the image doesn’t really matter that much - what’s important is the pixel format we use for loading. As with saving images for the web, it’s basically a question of balancing image quality and size.
kTexture2DPixelFormat_RGBA8888 is the default pixel format for textures, and provides the best image quality. It uses 8 bits for each colour (Red, Green and Blue), plus 8 bits for the alpha channel, for a total of 32 bits per pixel.
kTexture2DPixelFormat_RGBA4444 will use only 4 bits for each colour, plus 4 bits for the alpha channel, for a total of 16 bits per pixel. A texture stored in memory in this format will use half the size of one loaded with kTexture2DPixelFormat_RGBA8888.
For larger textures like atlases, this difference is very important. A 1024x1024 texture will use 4MB of texture memory when loaded with RGBA8888, but only 2MB of texture memory when loaded with RGBA4444!
Try to avoid using RGBA8888 unless you absolutely need the best possible quality for a particular texture. A lot of the time, you won’t even notice the difference between RGBA8888 and one of the other pixel formats. Gradients are a good example of where RGBA8888 is most useful:
To cut down on the number of times you have to set the pixel format, set it to the format you’re likely to use most often when your game starts:
[CCTexture2D setDefaultAlphaPixelFormat:kTexture2DPixelFormat_RGBA4444];
Then, whenever you need to change the pixel format for loading a particular texture, make sure you change it back afterwards:
[CCTexture2D setDefaultAlphaPixelFormat:kTexture2DPixelFormat_RGBA8888];
CCTexture2D *texture =
[[CCTextureCache sharedTextureCache] addImage:@"buttonsatlas.png"];
[texture setAliasTexParameters];
[CCTexture2D setDefaultAlphaPixelFormat:kTexture2DPixelFormat_RGBA4444];
Considering the pixel format you’ll end up using is important when planning your texture atlases. As each loaded atlas can only have one pixel format, you should try to ensure that you keep textures that require RGBA8888 together the same atlases, so you only have to use that pixel format for those textures.
A guide to the different pixel formats Cocos2d uses for textures, including hints on when to use each, appears here.
PVRTC
PVRTC is a special texture format you can use on iPhone OS devices. PVRTC textures take up less texture memory than regular textures of the same size, and can be drawn faster.
You can generate PVRTC textures from regular images using the texturetool program that comes with the Developer tools.
While PVRTC textures have some advantages, they also have one big disadvantage - compression artifacts.
The above image is probably showing the worst-case scenario - the kind of images for which PVRTC is least well suited. Space Harvest is a 2D game, so you’re basically always looking at the textures head on. Additionally, because the visual style of Space Harvest relies on crisp, non-antialiased graphics, artifacts are that much more visible.
In fact, PVRTC textures can be very useful, even in 2D games. For more detailed, anti-aliased sprites, or photorealistic textures, you might not even notice the difference. Space Harvest uses PVRTC for background images. But wherever clarity is very important, you should probably avoid them.
CCSpriteSheet
CCSpriteSheet is one way to unlock big performance improvements when drawing. Each sprite sheet has a texture atlas. When we create a sprite that uses that texture atlas, we can chose to attach our sprite to the sprite sheet by adding it as a child of the sprite sheet.
Why do this? Well, our sprite sheet will take over the drawing of our sprite. Rather than drawing each sprite individually, it will draw all sprites attached to that sprite sheet at once. This matters because one of the best ways to improve performance in an Open GL application is to cut down on the number of GL calls your code makes. Cocos2d handles most of the Open GL stuff for you, but it is helpful to have an understanding of what it’s doing behind the scenes.
Here is part of the draw method for CCSprite:
BOOL newBlend = NO;
if( blendFunc_.src != CC_BLEND_SRC || blendFunc_.dst != CC_BLEND_DST ) {
newBlend = YES;
glBlendFunc( blendFunc_.src, blendFunc_.dst );
}
#define kQuadSize sizeof(quad_.bl)
glBindTexture(GL_TEXTURE_2D, [texture_ name]);
int offset = (int)&quad_;
// vertex
int diff = offsetof( ccV3F_C4B_T2F, vertices);
glVertexPointer(3, GL_FLOAT, kQuadSize, (void*) (offset + diff) );
// color
diff = offsetof( ccV3F_C4B_T2F, colors);
glColorPointer(4, GL_UNSIGNED_BYTE, kQuadSize, (void*)(offset + diff));
// tex coords
diff = offsetof( ccV3F_C4B_T2F, texCoords);
glTexCoordPointer(2, GL_FLOAT, kQuadSize, (void*)(offset + diff));
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
if( newBlend )
glBlendFunc(CC_BLEND_SRC, CC_BLEND_DST);
(Emphasis mine, obviously)
Look at the number of calls to functions that begin with ‘gl’ - 7 calls in the worst case. This code will run every time we draw a sprite that isn’t attached to a sprite sheet. If we have 100 sprites, 700 calls, or 7000 gl calls for 1000 sprites.
CCSpriteSheet’s draw method is a bit more complex, and calls a separate method on it’s texture atlas to do the drawing. For brevity, I won’t repeat it here, but it looks like it makes around 10 gl calls. But crucially, it will only make those 10 calls to draw ALL of the sprites attached to our sprite sheet - 100 sprites will be 10 calls, even with 1000 sprites, it’ll still be 10 calls. In practice, this gives you a huge boost in drawing performance.
A note about depth sorting and CCSpriteSheet
If you need to depth-sort sprites from one atlas with sprites from another, things get a bit more complex.
By default, Cocos2d renders graphics using the Painter’s Algorithm. That means that objects are drawn in the order in which they appear in their parent node’s children array. The end result is that objects at the back are drawn first, objects that appear on top of everything else are drawn last.
This presents a problem if you need some objects attached to a particular sprite sheet to be drawn in front of those from another sprite sheet, but behind others from that same sprite sheet. By default, once the sprites from the first atlas have been drawn, the sprites from the second atlas will draw over the top of them, regardless of their z position relative to their siblings.
The way around this is to use CCNode’s vertexZ property. This gives you access to Open GL’s depth buffer, which allows you to draw your sprites in any order you like, and still allow them to be correctly depth sorted in relation to one another.
The biggest downside to this approach is that it can be difficult to get semi-transparent sprites to render properly, as the object directly behind them may not have been drawn when they come to be rendered. Apple’s advice is to draw semi-transparent objects last, which in practice means you’ll need to keep their sprite sheet in a higher position in its parent’s children array.
I didn't use vertexZ for depth sorting in Space Harvest - from the couple of days I spent experimenting with it, I found lots of little side effects that made it tricky to get things working the way I wanted. Regardless, try to use CCSpriteSheet as much as you can.
Pre-render programatically generated textures if you can
Some of the effects in Space Harvest are programatically generated using Core Graphics. Many objects have animations for taking damage and being destroyed - these are created by combining different images using different blending modes:
Originally, I generated textures for destroy animations for all my sprites when starting the game. However, Core Graphics is rather slow on the iPhone platform, so I eventually moved to saving the generated images out, pasting them into to my atlases in Photoshop, and loading them as regular textures in the final version. This cut around 10 seconds(!) off startup time, so if you do have any programatically generated textures that don't change, pre-rendering them is a good way to go.
Tuesday, October 19, 2010
How To Avoid Having Your App Rejected for Core Functionality Issues and Crashing
The two most common reasons for application rejection are issues with core functionality and crashing. Core functionality encompasses the belief that customers rightfully expect all the features described in the marketing text and release notes to work as described, and likewise that all the buttons and menu items within the application will be fully functional (i.e., no grayed out buttons or notifications that a feature will be implemented later). Before you submit your app for approval, make sure that every aspect of your application is fully functional and that the marketing text and release notes correspond to the end user experience.
Also, make sure you thoroughly test your application on iPhone and iPod touch in addition to the iPhone Simulator. A large percentage of applications are rejected due to various types of crashes, including crashes on launch, which would have been found and dealt with if they'd been tested on an actual device. Don't skip that step in the development process.
Also, make sure you thoroughly test your application on iPhone and iPod touch in addition to the iPhone Simulator. A large percentage of applications are rejected due to various types of crashes, including crashes on launch, which would have been found and dealt with if they'd been tested on an actual device. Don't skip that step in the development process.
Tutorials for iPad Development
While the iPad and iPhone share iOS as their operating system there are many aspects of development for the iPad that are considerably different and should be understood by developers looking to create the best possible iPad apps.
On this page I have decided to list tutorials specifically created for the iPad along with other resources such as user interface design tips, and graphical resources such as UI prototyping tools and vector kits.
You can expect this page to update with new tutorials and resources so be sure to bookmark it.
Newer resources appear towards the top of the listing.
1. Rapid Prototyping of iPad apps using Keynote – a great guide along with many interactive elements for prototyping (key here being interactive) using Keynote.
2. How To Port An App To the iPad – Covers how to convert your app to handle the iPad screen sizes, specifically autosizing and orientation, and when to use iPad elements.
3. Custom Input View Tutorial – A tutorial on how to create great looking custom input views on the iPad.
4. iPad Multitouch – A great example with code showing how to utilize all 11 available touches on the iPad.
5. UIPopoverController Tutorial - A tutorial on how to use the iPad UIPopoverController element.
6. iPhone To Hybrid – A guide to making apps that work on the different iOS platforms simultaneously with minimal work.
7. UISplitview Tutorial – A tutorial on how to use the specific iPad only UISplitview interface element.
8. Designing For iPad Reality Check – Brilliant in depth to guide to into how the interface of an iPad app should be developed.
9. iPad Application Design – A detailed look at some of the finer details of how to deisgn an iPad user interface.
10. iPad UI Graphic Kits - Several graphic kits for use in tools such as Photoshop and Omnigraffle.
11. Testing Out iPad Code With An iPhone or iPod Touch – Article about testing an iPad interface using the iSimulate iPhone app.
On this page I have decided to list tutorials specifically created for the iPad along with other resources such as user interface design tips, and graphical resources such as UI prototyping tools and vector kits.
You can expect this page to update with new tutorials and resources so be sure to bookmark it.
Newer resources appear towards the top of the listing.
1. Rapid Prototyping of iPad apps using Keynote – a great guide along with many interactive elements for prototyping (key here being interactive) using Keynote.
2. How To Port An App To the iPad – Covers how to convert your app to handle the iPad screen sizes, specifically autosizing and orientation, and when to use iPad elements.
3. Custom Input View Tutorial – A tutorial on how to create great looking custom input views on the iPad.
4. iPad Multitouch – A great example with code showing how to utilize all 11 available touches on the iPad.
5. UIPopoverController Tutorial - A tutorial on how to use the iPad UIPopoverController element.
6. iPhone To Hybrid – A guide to making apps that work on the different iOS platforms simultaneously with minimal work.
7. UISplitview Tutorial – A tutorial on how to use the specific iPad only UISplitview interface element.
8. Designing For iPad Reality Check – Brilliant in depth to guide to into how the interface of an iPad app should be developed.
9. iPad Application Design – A detailed look at some of the finer details of how to deisgn an iPad user interface.
10. iPad UI Graphic Kits - Several graphic kits for use in tools such as Photoshop and Omnigraffle.
11. Testing Out iPad Code With An iPhone or iPod Touch – Article about testing an iPad interface using the iSimulate iPhone app.
Tutorials for iPad Development
While the iPad and iPhone share iOS as their operating system there are many aspects of development for the iPad that are considerably different and should be understood by developers looking to create the best possible iPad apps.
On this page I have decided to list tutorials specifically created for the iPad along with other resources such as user interface design tips, and graphical resources such as UI prototyping tools and vector kits.
You can expect this page to update with new tutorials and resources so be sure to bookmark it.
Newer resources appear towards the top of the listing.
1. Rapid Prototyping of iPad apps using Keynote – a great guide along with many interactive elements for prototyping (key here being interactive) using Keynote.
2. How To Port An App To the iPad – Covers how to convert your app to handle the iPad screen sizes, specifically autosizing and orientation, and when to use iPad elements.
3. Custom Input View Tutorial – A tutorial on how to create great looking custom input views on the iPad.
4. iPad Multitouch – A great example with code showing how to utilize all 11 available touches on the iPad.
5. UIPopoverController Tutorial - A tutorial on how to use the iPad UIPopoverController element.
6. iPhone To Hybrid – A guide to making apps that work on the different iOS platforms simultaneously with minimal work.
7. UISplitview Tutorial – A tutorial on how to use the specific iPad only UISplitview interface element.
8. Designing For iPad Reality Check – Brilliant in depth to guide to into how the interface of an iPad app should be developed.
9. iPad Application Design – A detailed look at some of the finer details of how to deisgn an iPad user interface.
10. iPad UI Graphic Kits - Several graphic kits for use in tools such as Photoshop and Omnigraffle.
11. Testing Out iPad Code With An iPhone or iPod Touch – Article about testing an iPad interface using the iSimulate iPhone app.
On this page I have decided to list tutorials specifically created for the iPad along with other resources such as user interface design tips, and graphical resources such as UI prototyping tools and vector kits.
You can expect this page to update with new tutorials and resources so be sure to bookmark it.
Newer resources appear towards the top of the listing.
1. Rapid Prototyping of iPad apps using Keynote – a great guide along with many interactive elements for prototyping (key here being interactive) using Keynote.
2. How To Port An App To the iPad – Covers how to convert your app to handle the iPad screen sizes, specifically autosizing and orientation, and when to use iPad elements.
3. Custom Input View Tutorial – A tutorial on how to create great looking custom input views on the iPad.
4. iPad Multitouch – A great example with code showing how to utilize all 11 available touches on the iPad.
5. UIPopoverController Tutorial - A tutorial on how to use the iPad UIPopoverController element.
6. iPhone To Hybrid – A guide to making apps that work on the different iOS platforms simultaneously with minimal work.
7. UISplitview Tutorial – A tutorial on how to use the specific iPad only UISplitview interface element.
8. Designing For iPad Reality Check – Brilliant in depth to guide to into how the interface of an iPad app should be developed.
9. iPad Application Design – A detailed look at some of the finer details of how to deisgn an iPad user interface.
10. iPad UI Graphic Kits - Several graphic kits for use in tools such as Photoshop and Omnigraffle.
11. Testing Out iPad Code With An iPhone or iPod Touch – Article about testing an iPad interface using the iSimulate iPhone app.
Open Source Game Engine Comparison for iPhone
There are several open source game engines to choose from, and many cropping up all the time. On this page I have only listed those that I know have been used in games already available on the iPhone or iPad. I have chosen not to list those for which there are no apps available in the app store.
Choosing Your Open Source iPhone Game Engine
Sparrow Framework
The Sparrow Framework is a very lightweight 2D game engine created in Objective-C. In a very short amount of time I was able to understand the framework, and I find it to be very intuitive.
If you’d like to take a look at some actual coding with the Sparrow Framework be sure to check out the Beginners iPhone Action Game Programming Tutorial.
While I have not done much Flash game programming the developers state that the game engine was created with Flash game developers in mind.
The game framework includes all the necessary features you’d require for creating a basic 2D game such as easy animation, and a sound engine.
Cocos2D IPhone
The Cocos2D iPhone game engine is a port of a game engine originally created in Python and converted to iPhone Objective-C. As you can tell from the name, Cocos2D is designed for 2D games, that being said, although the engine is in a 2D world, the engine includes a growing collection of high quality 3D special effects.
Cocos2D has been used in many games on the iPhone app store, you can visit the official site here, where many are listed.
Cocos2D is the first engine to check out, while many may be turned off by the engine not supporting a 3d world, if you look at most of the top iPhone games the gameplay is 2D, in fact the iPhone’s touch screen controls can make it difficult to operate in a 3D world.
Also included is support for the in-game Chipmunk engine, and the latest version of Cocos also includes an OpenAL based sound engine.
The engine provides more examples than any of the other engines out there because of the large community. Overall I’d say the engine is as easy to use as any engine that does not have an environment editor.
Uses the LGPL license.
Sio2Engine
The SIO2 game engine is an excellent 3D game engine written in C. There is a free oepn source version, and a an indie version for $49. The free eidtion requires you to show a splash screen at the start of your game illustrating your use of the engine. This in my opinion is extremely fair considering the quality of the engine.
The game engine uses blender in it’s toolchain for scene and model creation. If you haven’t used Blender, it is a sophisticated open source 3D modeling program. In my opinion this is the only thing I don’t really like about sio2, while some love it, I can’t stand using blender as I’ve found it can’t compare to the top commercial modeling programs. Fortunately there are many blender plugins that allow you to import a wide variety of modeling formats.
SIO2 comes with an excellent set of tutorials, and provides support for sophisticated features such as skeletal animation, and soft-body physics which are explained in the tutorials.
I’ve found the performance of the latest version of the SIO2 game engine, version 1.4 to provide significantly better performance than previous versions. If you haven’t checked out SIO2 in awhile then I suggest you check it out again.
I recommend SIO2 to those who insist on a 3D world and thus can’t use Cocos.
Oolong Engine
The Oolong game engine is a 3D engine written in C++, and provides excellent performance. The downside of the Oolong engine is that it is difficult to use for those that are not familiar with OpenGL ES.
Oolong provides support for a wide variety of features, and very good performance, as I said my only problem with Oolong is that it is difficult to use. This is a low-level engine designed for programmers so if you’re just getting into game development I would stay away.
You will find the latest version on google code, there is very little documentation for Oolong, but the community is very active, and you can get answers to many of your questions there.
I would recommend Oolong to those looking to create their own game engine looking for something to start with.
Uses the MIT license.
Irrlicht Engine
I mention Irrlicht here only because I received a message from someone stating that it was available on the iPhone. I know that it has been used in the creation of apps already available on the iPhone.
The Irrlicht game engine is a 3D game engine written in C++.
While there is no official port available on the Irrlicht website for the iPhone with some tinkering I was able to get the OpenGL ES version running on the iPhone — somewhat. You will find the OpenGL ES version hidden away in the repository.
Irrlicht is an excellent open source engine that has support for an extremely wide variety of file formats, and has the best support for the “classic” BSP format that I’ve seen in an open source game engine. There are also numerous other tools that have been created for the engine.
All this being said, I can’t recommend Irrlicht because there is no official port, and if you check out the forums there really is no one willing to provide help to those looking to get it running on the iPhone although some have created apps running on the iPhone.
The Irrlicht engine uses the Zlib license.
Summary
The Sparrow Framework makes an excellent first choice for those developing a 2D iPhone game. Cocos2D is the most popular, and has the most support but is less intuitive. You will learn Objective-C while using the engine, and the engine has been proven in a wide variety of games.
For 3D games my choice is SIO2, although I’m not a fan of blender this does make it more accessible than the other proven 3D iPhone game engines.
Choosing Your Open Source iPhone Game Engine
Sparrow Framework
The Sparrow Framework is a very lightweight 2D game engine created in Objective-C. In a very short amount of time I was able to understand the framework, and I find it to be very intuitive.
If you’d like to take a look at some actual coding with the Sparrow Framework be sure to check out the Beginners iPhone Action Game Programming Tutorial.
While I have not done much Flash game programming the developers state that the game engine was created with Flash game developers in mind.
The game framework includes all the necessary features you’d require for creating a basic 2D game such as easy animation, and a sound engine.
Cocos2D IPhone
The Cocos2D iPhone game engine is a port of a game engine originally created in Python and converted to iPhone Objective-C. As you can tell from the name, Cocos2D is designed for 2D games, that being said, although the engine is in a 2D world, the engine includes a growing collection of high quality 3D special effects.
Cocos2D has been used in many games on the iPhone app store, you can visit the official site here, where many are listed.
Cocos2D is the first engine to check out, while many may be turned off by the engine not supporting a 3d world, if you look at most of the top iPhone games the gameplay is 2D, in fact the iPhone’s touch screen controls can make it difficult to operate in a 3D world.
Also included is support for the in-game Chipmunk engine, and the latest version of Cocos also includes an OpenAL based sound engine.
The engine provides more examples than any of the other engines out there because of the large community. Overall I’d say the engine is as easy to use as any engine that does not have an environment editor.
Uses the LGPL license.
Sio2Engine
The SIO2 game engine is an excellent 3D game engine written in C. There is a free oepn source version, and a an indie version for $49. The free eidtion requires you to show a splash screen at the start of your game illustrating your use of the engine. This in my opinion is extremely fair considering the quality of the engine.
The game engine uses blender in it’s toolchain for scene and model creation. If you haven’t used Blender, it is a sophisticated open source 3D modeling program. In my opinion this is the only thing I don’t really like about sio2, while some love it, I can’t stand using blender as I’ve found it can’t compare to the top commercial modeling programs. Fortunately there are many blender plugins that allow you to import a wide variety of modeling formats.
SIO2 comes with an excellent set of tutorials, and provides support for sophisticated features such as skeletal animation, and soft-body physics which are explained in the tutorials.
I’ve found the performance of the latest version of the SIO2 game engine, version 1.4 to provide significantly better performance than previous versions. If you haven’t checked out SIO2 in awhile then I suggest you check it out again.
I recommend SIO2 to those who insist on a 3D world and thus can’t use Cocos.
Oolong Engine
The Oolong game engine is a 3D engine written in C++, and provides excellent performance. The downside of the Oolong engine is that it is difficult to use for those that are not familiar with OpenGL ES.
Oolong provides support for a wide variety of features, and very good performance, as I said my only problem with Oolong is that it is difficult to use. This is a low-level engine designed for programmers so if you’re just getting into game development I would stay away.
You will find the latest version on google code, there is very little documentation for Oolong, but the community is very active, and you can get answers to many of your questions there.
I would recommend Oolong to those looking to create their own game engine looking for something to start with.
Uses the MIT license.
Irrlicht Engine
I mention Irrlicht here only because I received a message from someone stating that it was available on the iPhone. I know that it has been used in the creation of apps already available on the iPhone.
The Irrlicht game engine is a 3D game engine written in C++.
While there is no official port available on the Irrlicht website for the iPhone with some tinkering I was able to get the OpenGL ES version running on the iPhone — somewhat. You will find the OpenGL ES version hidden away in the repository.
Irrlicht is an excellent open source engine that has support for an extremely wide variety of file formats, and has the best support for the “classic” BSP format that I’ve seen in an open source game engine. There are also numerous other tools that have been created for the engine.
All this being said, I can’t recommend Irrlicht because there is no official port, and if you check out the forums there really is no one willing to provide help to those looking to get it running on the iPhone although some have created apps running on the iPhone.
The Irrlicht engine uses the Zlib license.
Summary
The Sparrow Framework makes an excellent first choice for those developing a 2D iPhone game. Cocos2D is the most popular, and has the most support but is less intuitive. You will learn Objective-C while using the engine, and the engine has been proven in a wide variety of games.
For 3D games my choice is SIO2, although I’m not a fan of blender this does make it more accessible than the other proven 3D iPhone game engines.
Subscribe to:
Posts (Atom)