|
BestPractices
cocos2d for iPhone best practices
DEPRECATEDDEPRECATED DEPRECATED Use this page instead: http://www.cocos2d-iphone.org/wiki/doku.php/best_practices IntroductioniPhone is a very nice device. Although it has very nice and powerful features, you must be careful when programming for it. So here are the cocos2d (and general) best-practices. DetailsImproving performance
// must be called before any other call to the director
[Director useFastDirector];
[Texture2D setDefaultAlphaPixelFormat:kTexture2DPixelFormat_RGBA4444]; // add this line at the very beginning Sprite *sprite = [Sprite spriteWithFile: @"sprite.pvr"]; Reducing Memory
// textures with retain count 1 will be removed // you can add this line in your scene#dealloc method [[TextureMgr sharedTextureMgr] removeUnusedTextures]; // since v0.8 // removes a certain texture from the cache Texture2D *texture = [sprite texture]; [[TextureMgr sharedTextureMgr] removeTexture: texture]]; // available in v0.7 too // removes all textures... only use when you receive a memory warning signal [[TextureMgr sharedTextureMgr] removeAllTextures]; // available in v0.7 too Timers
/**********************************************************/
// OK OK OK OK OK
/**********************************************************/
-(id) init
{
if( ! [super init] )
return nil;
// schedule timer
[self schedule: @selector(tick:)];
[self schedule: @selector(tick2:) interval:0.5];
return self;
}
-(void) tick: (ccTime) dt
{
// bla bla bla
}
-(void) tick2: (ccTime) dt
{
// bla bla bla
}
/**********************************************************/
// BAD BAD BAD BAD
/**********************************************************/
// Why BAD ?
// You can't pause the game automagically.
-(void) onEnter
{
[super onEnter];
timer1 = [NSTimer scheduledTimerWithTimeInterval:1/FPS target:self selector:@selector(tick1) userInfo:nil repeats:YES];
timer2 = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(tick2) userInfo:nil repeats:YES];
}
-(void) onExit
{
[timer1 invalidate];
[timer2 invalidate];
[super onExit];
}
-(void) tick
{
// bla bla bla
}
-(void) tick2
{
// bla bla bla
}
draw vs update
/**********************************************************/
// OK OK OK OK OK
/**********************************************************/
-(void) draw
{
[item draw]; // OK: DRAW INSIDE DRAW
}
-(void) tick:(ccTime) dt
{
item.position = dt * finalPosition; // OK, UPDATE STATE IN SCHEDULED SELECTOR
}
/**********************************************************/
// BAD BAD BAD BAD 1
/**********************************************************/
-(void) draw
{
dt = [self calculateDelta]; // DONT UPDATE STATE IN DRAW.
item.position = dt * finalPosition; // Pause won't work
[item draw];
}
/**********************************************************/
// BAD BAD BAD BAD 2
/**********************************************************/
-(void) tick:(ccTime) dt
{
item.position = dt * finalPosition;
[item draw]; // <--- DON'T DRAW IN SCHEDULED SELECTOR
// because transformations won't alter your image
}
Director flow control
// TRY TO AVOID A BIG STACK OF PUSHED SCENES
-(void) mainMenu()
{
// etc
[[Director sharedDirector] pushScene: gameScene];
}
// stack:
// . game <-- running scene
// . mainMenu
-(void) game
{
[[Director sharedDirector] pushScene: gameOverScene];
}
// stack:
// . gameOver <-- running scene
// . game
// . mainMenu
-(void) showGameOver
{
[[Director sharedDirector] pushScene: hiScoreScene];
}
// stack:
// . scores <-- running scene (4 pushed scenes... expensive)
// . gameOver
// . game
// . mainMenu
Creating Nodes (Sprites, Labels, etc..)
/**********************************************************/
// OK, MOST OF THE TIME
/**********************************************************/
-(id) init
{
// etc...
sprite1 = [Sprite1 create]; // <-- USUALLY IT IS BETTER TO CREATE OBJECTS IN INIT
// etc...
}
-(void) tick: (ccTime) dt
{
// etc...
if( someThing ) {
[sprite1 show]; // <--- BUT IF YOU DON'T USE THEM FREQUENTLY, MEMORY IS WASTED
}
}
/**********************************************************/
// BAD, MOST OF THE TIME
/**********************************************************/
-(void) tick: (ccTime) dt
{
// etc...
if( someThing ) {
sprite = [Sprite1 create]; // <--- EXEPENSIVE
[sprite1 show];
//...
[sprite1 release]; // <- AT LEAST MEMORY IS RELEASED
}
}
Hierarchy of Layers
Actions
Buttons
how does the pause/resume works ?
|
Sign in to add a comment
I'd like to add that you should make sure "thumb compilation" under build settings in your project is OFF. It's off in the Cocos2D Xcode project, but if you create your own project and add the Cocos2D files to it, it will be on by default. You will see a SIGNIFICANT performance increase by turning this off.