【第一段代码】:
Sprite1::Sprite1()
{
setTouchEnabled( true );
CCSize s = CCDirector::sharedDirector()->getWinSize();
addNewSpriteWithCoords( ccp(s.width/2, s.height/2) );
}
void Sprite1::addNewSpriteWithCoords(CCPoint p)
{
int idx = (int)(CCRANDOM_0_1() * 1400.0f / 100.0f);
int x = (idx%5) * 85;
int y = (idx/5) * 121;
CCSprite* sprite = CCSprite::create("Images/grossini_dance_atlas.png", CCRectMake(x,y,85,121) );
addChild( sprite );
sprite->setPosition( ccp( p.x, p.y) );
CCActionInterval* action;
float random = CCRANDOM_0_1();
if( random < 0.20 )
action = CCScaleBy::create(3, 2);
else if(random < 0.40)
action = CCRotateBy::create(3, 360);
else if( random < 0.60)
action = CCBlink::create(1, 3);
else if( random < 0.8 )
action = CCTintBy::create(2, 0, -255, -255);
else
action = CCFadeOut::create(2);
CCActionInterval* action_back = action->reverse();
CCActionInterval* seq = (CCActionInterval*)(CCSequence::create( action, action_back, NULL ));
sprite->runAction( CCRepeatForever::create(seq) );
}
【第二段代码】:
SpriteBatchNode1::SpriteBatchNode1()
{
setTouchEnabled( true );
CCSpriteBatchNode* BatchNode = CCSpriteBatchNode::create("Images/grossini_dance_atlas.png", 50);
addChild(BatchNode, 0, kTagSpriteBatchNode);
CCSize s = CCDirector::sharedDirector()->getWinSize();
addNewSpriteWithCoords( ccp(s.width/2, s.height/2) );
}
void SpriteBatchNode1::addNewSpriteWithCoords(CCPoint p)
{
CCSpriteBatchNode* BatchNode = (CCSpriteBatchNode*) getChildByTag( kTagSpriteBatchNode );
int idx = CCRANDOM_0_1() * 1400 / 100;
int x = (idx%5) * 85;
int y = (idx/5) * 121;
CCSprite* sprite = CCSprite::createWithTexture(BatchNode->getTexture(), CCRectMake(x,y,85,121));
BatchNode->addChild(sprite);
sprite->setPosition( ccp( p.x, p.y) );
CCActionInterval* action;
float random = CCRANDOM_0_1();
if( random < 0.20 )
action = CCScaleBy::create(3, 2);
else if(random < 0.40)
action = CCRotateBy::create(3, 360);
else if( random < 0.60)
action = CCBlink::create(1, 3);
else if( random < 0.8 )
action = CCTintBy::create(2, 0, -255, -255);
else
action = CCFadeOut::create(2);
CCActionInterval* action_back = action->reverse();
CCActionInterval* seq = (CCActionInterval*)(CCSequence::create(action, action_back, NULL));
sprite->runAction( CCRepeatForever::create(seq));
}
这两个部分的代码完成的功能是一样的,但是仔细看发现这是两种方式,第一种每次事件响应的时候就会加载“Images/grossini_dance_atlas.png”图片,然后截取某一部分创建精灵,第二种方式是在创建开始时,用CCSpriteBatchNode类加载该图片,以后再使用时直接调用该对象,从而能得到纹理,然后再创建精灵。
每当cocos2d在屏幕上回执一个纹理(一张图片)时,图形硬件都需要做前后三个动作:准备渲染、渲染图形和渲染后的清除。这些工作产生了一个纹理所共有的开销。如果要缓解此状况(大量的图形渲染造成大量的开销),就需要让硬件知道需要进行渲染的这一组精灵使用的是同一纹理。这样图形硬件就会为这组精灵只进行一次准备、渲染和清除的工作。有没有完过雷电类的游戏,想象一下,当你发出大量的子弹时,若是按照一般的做法每个子弹都渲染一次的话,开销会很大。游戏开发不像应用,大量的动画图片,高速的计算,大量的图形占用,所以我们不得不将图形优化放到一个很高的位置,好在cocos2d在这一块儿上封装得很好,我们只需要了解一下一些类的基本用法,就可以很简单地优化代码;
(1.)有一张png图片"fish.png“,我们需要通过其创建一个精灵添加到层上,那么传统的方式就是:
CCSprite *fishSprite = [CCSprite spriteWithFile:@"fish.png"];
[layer addChild:fishSprite];
如果该层上有10个精灵呢?那就加个for循环,代码上我们感觉效率不低,但在硬件底层,openGL在绘制的时候每次绘制一个精灵,都要有一个准备的过程,形象的说,就像一个画家要画十只鱼,画一只鱼的时候,需要准备调色盘,画笔,画完一只,收起来;画第二只的时候,再准备调色盘,再画,画完再收好;如此十次,画得越多,耽误的越多;这样说的话你就会觉得这个画家有点二,但是传统的绘制精灵还真就是这样,机器不是人,他是不知道自己变通的;
(2.) 所以我们就要用到CCSpriteBatchNode了,上面的代码我们可以这样来改动:
CCSpriteBatchNode *fishBatch = [CCSpriteBatchNode batchNodeWithFile :@"fish.png"];
[layer addChild:fishBatch];
CCSprite *fishSprite = CCSprite::createWithTexture(BatchNode->getTexture());
[fishBatch addChild:fishSprite];
这样写你可能不觉得有什么优化,但是fishBatch里面添加的精灵越多,其优势就越明显,还是刚才的例子,之前每画一条鱼,都会准备,绘制,收起;现在将精灵添加进fishBatch,就像这个画家知道一次性要画多少条鱼,就不会那么死板的进行一次又一次额外重复的工作了;
1、CCSpriteBatchNode中添加的精灵所依赖的生成纹理必须是一样,包括生成CCSpriteBatchNode对象时所使用的纹理;
2、所有添加进去的精灵,z轴都是一样的,即都依赖于CCSSpriteBatchNode对象的z轴;
http://www.apkbus.com/android-854-1.html
http://hi.baidu.com/gamestests/item/d0a28a18f3e27a36b9318025