Cocos2d Best Practices
Improving Performance Improvement
- Use this wizard: performance tests
- Disable thumb editing in xcode
- ThumbCodeMuch slower than non-thumb code
- Director:
- Use
Fastdirector
.Fastdirector
Vertical synchronization is much faster than normal ctor.
// Must be called before any other call to the Director[Director usefastdirector];
-
- If you use
Director
There will be a 1/240 wait
// If you are using "normal" director you cocould set a very low Interval[[Director shareddire]Setanimationinterval:1/240.0];
- How to use it as follows:
- Use
Atlassprite
ReplaceSprite
- Use
Bitmapfontatlas
OrLabelatlas
SubstitutionLabel
- Use
Tilemapatlas
While giving up tiles
This version of Atlas provides faster implementation and reduces code overhead and complexity. In Atlas, atlasmanager is used to save a large image in a frame. Each object in the fram framework is referenced by a large image in the framework. It saves the number of textures and calls for opengles acceleration.
Atlas is a manual or table. In this content, it means that it has a large image that can be read into the OpenGL texture. In fact, it saves a series of small images.
- Use a 4-bit or 16-bit texture if possible
- 16-bit textures for PNG/GIF/BMP/tiff Images
[Texture2d setdefaultalphapixelformat:Ktexture2dpixelformat_rgba4444];// Add this line at the very beginning
-
- 4-bit or 2-bit texture: Use pvrtc texture.
Sprite*Sprite= [Sprite spritewithfile: @"Sprite. PVR"];
-
- Use 32-bit texture as the final choice
Memory switching memory reduces memory overhead
- Use 16-bit or 4-bit textures
- Use
Texturemgr
Texturemgr
Cache all images
- Even when the image is not used anymore, it will remain in memory
- The following methods can be used to remove data from memory:
// Textures with retain count 1 will be removed // Use this method at the end of sence to eliminate useless objects # dealloc Method [ [ Texturemgr sharedtexturemgr ] Removeunusedtextures ] ; // Since v0.8 // Clear the cache from a specific texture Texture2d * Texture= [ Sprite texture ] ; [ [ Texturemgr sharedtexturemgr ] Removetexture : Texture ] ] ; // Available in v0.7 too // Remove all texture... when receiving a memory warning [ [ Texturemgr sharedtexturemgr ] Removealltextures ] ; // Available in v0.7 too
Timers Timer
- Try not to use
Nstimer
And use the scheduler that comes with cocos2d.
- If you use scheduler, you will have:
- Automatic pause and recovery.
- When the layer (scene, Sprite, cocosnode) enters the stage the timer will be automatically activated, and when it leaves the stage it will be automatically deactivated.
- Your target/selector will be called with a Delta time
/*************************************** *******************/// The next step is OK.
/*************************************** *******************/ - ( ID ) Init { If ( ( Self = [ Super init ] ) ) { // Schedule timer [ Self schedule : @ Selector ( Tick : ) ] ; [ Self schedule : @ Selector ( Tick2 : ) Interval : 0.5 ] ; } Return Self; } - ( Void ) Tick : ( Cctime ) DT{ // Bla } - ( Void ) Tick2 : ( Cctime ) DT { // Bla } /*************************************** *******************/ // The following is a recommended method
/*************************************** *******************/ // Why bad? // Why Not? Because you cannot make it stop automatically. - ( 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 } - ( Void ) Tick2 { // Bla }
Draw vs update plotting and updating
- try not to update any state variable inside the draw selector. Do not update the state of the variable in the draw selector.
- try not to draw anything inside a scheduled selector. Do not draw anything in scheduled selector.
- instead update the state variables inside a scheduled selector. It is best to update the state variable in scheduled selector
- instead draw everything inside the draw selector draw in the draw selector
- If you update state variables inside the draw selector, the pause/resume won't work as expected.
- if you draw something inside a scheduled selector, it can't be transformed. If you draw in scheduled selector, it cannot be converted.
- draw is called every frame
- scheduled selectors can be called with any frame rate, but no more frequently than the application's FPS rate. scheduled selectors can be called by any frame, but no application has a high FPS call rate.
/********************** ***********************************/ // the following code is very OK /*********** **************************************** * ******/ - ( void ) draw { [ item draw ] ; // OK: draw Inside draw } - ( void ) tick : ( cctime ) dt { item. position = dt * finalposition; // OK, update state in scheduled selector }: it is best to call draw in the draw method
Use update in scheduled Selector
/*************************************** *******************/// Check the following code for bad 1:/*************************************** *******************/-(Void)Draw{DT= [Self calculatedelta];// Dont update state in draw.Item. Position=DT*Finalposition;// Pause won't work[Item draw];}Translator's conclusion: Do not call update in draw
And stops working.
/*************************************** *******************/// Another piece of bad code 2/*************************************** *******************/-(Void)Tick:(Cctime)DT{Item. Position=DT*Finalposition;[Item draw];// & Lt; --- don't draw in scheduled Selector// Because transformations won't alter your image}
Do not use the draw method in scheduled selector.
Because transformations does not change the image
Director Flow Control
- Use
Replacescene
InsteadPushscene
Pushscene
Very convenient, but it will push scene to the memory. The memory in the iPhone is too valuable.
// Reduce the number of times that scenes is pushed to the memory Stack
- ( Void ) Mainmenu ( ) { // Etc [ [ Director shareddire ] Pushscene : Gamescene ] ; } // Stack: //. Game & lt; -- running scene //. Mainmenu - ( Void ) Game { [ [ Director shareddire ] Pushscene : Gameoverscene ] ;} // Stack: //. Gameover & lt; -- running scene //. Game //. Mainmenu - ( Void ) Showgameover { [ [ Director shareddire ] Pushscene : Hiscorescene ] ; } // Stack: //. Scores & lt; -- running scene (4 pushed scenes... expensive) //. Gameover //. Game //. Mainmenu
Creating nodes (sprites, labels, Etc ..) Create nodes (genie, tags, etc)
- If possible, create a cocosnode object (genie, Tag, layer, etc.) or any other object in the selector, and try not to initialize it in the draw function or in it.
- Creating a node has a high overhead. Try to pre-create the node as much as possible.
- On the other hand, be careful with memory operations and do not cause many unnecessary objects in it.
/*************************************** *******************/ // OK. This is often used in many cases. /*************************************** *******************/ - ( ID ) Init { // Etc... Sprite1 = [ Sprite1 create ] ; // & Lt; -- usually this is the case // Etc... } - ( Void ) Tick : ( Cctime ) DT{ // Etc... If ( Something ) { [ Sprite1 show ] ; // & Lt; --- if you do not use it frequently, the memory will be wasted. } } /*************************************** *******************/ // Bad. This is not good. /*************************************** *******************/ - ( Void ) Tick : ( Cctime ) DT { // Etc... If ( Something ) { Sprite = [ Sprite1 create ] ; // & Lt; --- our expensive memory overhead [ Sprite1 show ] ; //... [ Sprite1 release ] ; // & Lt;-at least the memory is released } }
Hierarchy of layers class
- Never create a layer with many levels. Try to create as few layers as possible.
Actions
- It is expensive to create certain actions, since it might require a lot
Malloc ()
. For example:Sequence
OfSpawn
WithRotateby
With a anotherSequence
, Etc... Is very expensive.
- So try to reuse actions.
- Once the action is used, save it for later if you know you will execute that type of action again. Then, instead of allocing a new action, you can just initialize it.
Put this at the end: the province's crawlers have no source.
Translator: alexliu (Alex DOTNET learning)
: Http://alexliu.cnblogs.com/