CCSpriteBatchNode

转载 2013年12月05日 14:06:47
  一般游戏图片资源会打包成一张大图,这样节省空间,又提升速度。打包工具有Zwoptex和texturepacker等等。

   CCSpriteBatchNode的初始化只要一张图片,也就是那张大图。然后把所有用到那张大图里面的小图的sprite都加到 CCSpriteBatchNode的child,绘制效率就会提高。下面是TestCpp中的Demo,SpriteTest

SpriteBatchNode1::SpriteBatchNode1()
{
    setTouchEnabled( true );//让当前Layer接收触摸事件

                                                             //创建SpriteBatchNode对象和CCTextureAtlas四边形的容量(缺省29)
    CCSpriteBatchNode* BatchNode = CCSpriteBatchNode::create("Images/grossini_dance_atlas.png", 50);

   //首先要把batchNode添加到Layer 可以通过kTagSpriteBatchNode引用

    addChild(BatchNode, 0, kTagSpriteBatchNode);
    CCSize s = CCDirector::sharedDirector()->getWinSize();
    addNewSpriteWithCoords( ccp(s.width/2, s.height/2) );//添加一个子Sprite,所有的Sprite是添加到batchNode的child Sprite
}
void SpriteBatchNode1::addNewSpriteWithCoords(CCPoint p)
{
    CCSpriteBatchNode* BatchNode = (CCSpriteBatchNode*) getChildByTag( kTagSpriteBatchNode );//得到BatchNode
    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));//创建Sprite
    BatchNode->addChild(sprite); //将创建好的Sprite添加到BatchNode
   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));//在新创建的Sprite中应用动画
}
void SpriteBatchNode1::ccTouchesEnded(CCSet* touches, CCEvent* event)
{
    CCSetIterator it;
    CCTouch* touch;
    for( it = touches->begin(); it != touches->end(); it++) 
    {
        touch = (CCTouch*)(*it);
       if(!touch)
            break;
      CCPoint location = touch->getLocation();
        addNewSpriteWithCoords( location );//在触摸点添加Sprite层
    }
}

/////////////////////////////////////对SpriteBatchNode中的Sprite进行排序

void SpriteBatchNodeZOrder::reorderSprite(float dt)
{
    CCSpriteBatchNode* batch= (CCSpriteBatchNode*)(getChildByTag( kTagSpriteBatchNode ));
    CCSprite* sprite = (CCSprite*)(batch->getChildByTag(kTagSprite1));
     int z = sprite->getZOrder();
        if( z < -1 )
        m_dir = 1;
    if( z > 10 )
        m_dir = -1;
        z += m_dir * 3;
    batch->reorderChild(sprite, z);
}

/////////////////////////////////对SpriteBatchNode中的Sprite进行remove和add

void SpriteBatchNodeColorOpacity::removeAndAddSprite(float dt)
{    CCSpriteBatchNode* batch= (CCSpriteBatchNode*)(getChildByTag( kTagSpriteBatchNode ));
    CCSprite* sprite = (CCSprite*)(batch->getChildByTag(kTagSprite5));
        sprite->retain();
    batch->removeChild(sprite, false);
    batch->addChild(sprite, 0, kTagSprite5);
       sprite->release();
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////

//在运行时动态修改纹理,适用于NPC升级,会影响所有的child Sprite

  CCSpriteBatchNode* batch = (CCSpriteBatchNode*) getChildByTag( kTagSpriteBatchNode );
    if( batch->getTexture() == m_texture1 )
        batch->setTexture(m_texture2);
    else
        batch->setTexture(m_texture1); 

////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//SpriteFrameCatcher与SpriteBatchNode结合使用

void SpriteFrameTest::onEnter()
{
    SpriteTestDemo::onEnter();
    CCSize s = CCDirector::sharedDirector()->getWinSize();
    // IMPORTANT(重要声明):
    // The sprite frames will be cached AND RETAINED, and they won't be released unless you call

  //SpriteFames被缓存和重新引用,需要在不用的适用调用下面方法释放这些SpriteFrames
    //     CCSpriteFrameCache::sharedSpriteFrameCache()->removeUnusedSpriteFrames);
    CCSpriteFrameCache* cache = CCSpriteFrameCache::sharedSpriteFrameCache();
    cache->addSpriteFramesWithFile("animations/grossini.plist");
    cache->addSpriteFramesWithFile("animations/grossini_gray.plist", "animations/grossini_gray.png");
    cache->addSpriteFramesWithFile("animations/grossini_blue.plist", "animations/grossini_blue.png");
    //
    // Animation using Sprite BatchNode 使用BatchNode创建动画
    m_pSprite1 = CCSprite::createWithSpriteFrameName("grossini_dance_01.png");//从SpriteFameCache中创建一个Sprite
    m_pSprite1->setPosition( ccp( s.width/2-80, s.height/2) );
    CCSpriteBatchNode* spritebatch = CCSpriteBatchNode::create("animations/grossini.png");//创建SpriteBatchNode 这里要和CCSpriteFrameCache一致
    spritebatch->addChild(m_pSprite1);//将Sprite添加到SpriteBatchNode

    addChild(spritebatch); //将SpriteBatchNode添加到当前layer
    CCArray* animFrames = CCArray::createWithCapacity(15);
    char str[100] = {0};
    for(int i = 1; i < 15; i++) 
    {
        sprintf(str, "grossini_dance_%02d.png", i);
        CCSpriteFrame* frame = cache->spriteFrameByName( str );  //创建动画的多帧SpriteFrame
        animFrames->addObject(frame);  //添加到CCArray集合
    }
    CCAnimation* animation = CCAnimation::createWithSpriteFrames(animFrames, 0.3f);//创建动画对象

    m_pSprite1->runAction( CCRepeatForever::create( CCAnimate::create(animation) ) );//Sprite载入动画Action
   // to test issue #732, uncomment the following line
    m_pSprite1->setFlipX(false);
    m_pSprite1->setFlipY(false);
    //
    // Animation using standard Sprite,根据标准的Sprite创建动画
    //
    m_pSprite2 = CCSprite::createWithSpriteFrameName("grossini_dance_01.png");
    m_pSprite2->setPosition( ccp( s.width/2 + 80, s.height/2) );
    addChild(m_pSprite2);
   CCArray* moreFrames = CCArray::createWithCapacity(20);
    for(int i = 1; i < 15; i++) 
    {
        sprintf(str, "grossini_dance_gray_%02d.png",i);
        CCSpriteFrame *frame = cache->spriteFrameByName(str);
        moreFrames->addObject(frame);
    }
   for( int i = 1; i < 5; i++) {
        sprintf(str, "grossini_blue_%02d.png",i);
        CCSpriteFrame *frame = cache->spriteFrameByName(str);
        moreFrames->addObject(frame);
    }
 // append frames from another batch
    moreFrames->addObjectsFromArray(animFrames);
    CCAnimation *animMixed = CCAnimation::createWithSpriteFrames(moreFrames, 0.3f);
   m_pSprite2->runAction(CCRepeatForever::create( CCAnimate::create(animMixed) ) );
   // to test issue #732, uncomment the following line
    m_pSprite2->setFlipX(false);
    m_pSprite2->setFlipY(false);

  schedule(schedule_selector(SpriteFrameTest::startIn05Secs), 0.5f);
    m_nCounter = 0;
}
void SpriteFrameTest::onExit()  //释放CCSpriteFrameCache中没有使用的SpriteFrame
{
    SpriteTestDemo::onExit();
    CCSpriteFrameCache *cache = CCSpriteFrameCache::sharedSpriteFrameCache();
    cache->removeSpriteFramesFromFile("animations/grossini.plist");
    cache->removeSpriteFramesFromFile("animations/grossini_gray.plist");
    cache->removeSpriteFramesFromFile("animations/grossini_blue.plist");
}

CCTextureAtlas 纹理图集。说白了,它本身保存一张大图的纹理和一个记录画大图某一区域的信息结构体的数组。

由于CCTextureAtlas使用了opengl的VBO(顶点数组对象),所以用CCTextureAtlas所作的绘制在效率上比较高。

下面介绍一下该类的成员:

1.GLuint   m_pBuffersVBO[2],这是两个opengl VBO的句柄。一个用来做顶点数组句柄,一个用来做顶点索引数组句柄。

2.GLushort   *m_pIndices,这是一个顶点索引数组的类本地备份。

3 ccV3F_C4B_T2F_Quad *  m_pQuads ,这是一个顶点数组的类本地备份。这应该是CCTextureAtlas类实现的核心,所有该类的功能都再围绕该结构体在做操纵。

4. CCTexture2D  *m_pTexture,这是保存大图的纹理对象。

5  int  m_uCapacity,四边形的容量。

6 int  m_uTotalQuads,实际上使用的四边形的数目。

7 m_bDirty ,当前opengl VBO中的数据是否是脏数据。为什么会存在这么一个类呢?实际上因为CCTextureAtlas容许你动态改变它管理的四边形数据,一旦你改变了该数据就需要一个标志位告诉该类在绘制四边形的时候把VBO中得数据更新掉。该成员就是起这个作用。

相关文章推荐

2dx ccspritebatchnode

  • 2014年03月12日 15:37
  • 8.72MB
  • 下载

精灵集合类CCSpriteBatchNode与精灵帧缓冲类CCSpriteFrameCache的混合使用

1.用途 CCSpriteBatchNode    精灵集合类        优化渲染次数 CCSpriteFrameCache  精灵帧缓冲类     优化运行内存 2.代码  ...

CCSpriteBatchNode与CCTextureAtlas详解

一般游戏图片资源会打包成一张大图,这样节省空间,又提升速度。打包工具有Zwoptex和texturepacker等等。    CCSpriteBatchNode的初始化只要一张图片,也就是那...

Cocos2d-x 利用CCSpriteBatchNode建立子弹池

Cocos2d-x 利用CCSpriteBatchNode建立子弹池 我们要实现如何利用CCSpriteBatchNode建立对象,CCSpriteBatchNode的好处是只渲染一...
  • qqMCY
  • qqMCY
  • 2013年06月28日 13:58
  • 1454

Cocos2d-x利用CCSpriteBatchNode提高渲染效率

猴子原创,欢迎转载。转载请注明: 转载自Cocos2D开发网--Cocos2Dev.com,谢谢!原文地址: http://www.cocos2dev.com/?p=331以前写过一个游戏中的天气系统...

CCSpriteBatchNode与"pvr.ccz","plist"精灵优化及注意事项

本站文章均为 李华明Himi 原创,转载务必在明显处注明: 转载自【黑米GameDev街区】 原文链接: http://www.himigame.com/iphone-cocos2d/465...

CCSpriteBatchNode

一般游戏图片资源会打包成一张大图,这样节省空间,又提升速度。打包工具有Zwoptex和texturepacker等等。    CCSpriteBatchNode的初始化只要一张图片,也就是那张大图。...
  • trandy
  • trandy
  • 2011年08月04日 21:38
  • 1310

cocos2d - CCSpriteBatchNode的使用

有点:CCSpriteBatchNode 中的所有CCSprite只会被渲染1次,因此可以提高游戏的FPS。 限制:加入到 CCSpriteBatchNode 中的CCSprite必须使用同一张纹理...

Cocos2d-X 学习笔记 20 利用CCSpriteBatchNode提高渲染效率

原文地址: http://www.cocos2dev.com/?p=331 以前写过一个游戏中的天气系统,今天有人说我的天气系统有点卡,不是很好用。我看下了他的代码,发现他改了我的代...

cocos2d-x学习笔记(21)--CCSpriteBatchNode

cocos2d-x学习笔记(21)--CCSpriteBatchNode  本文出自http://www.wenbanana.com稻草人博客,欢迎访问! 注意:从cocos2d-x学...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:CCSpriteBatchNode
举报原因:
原因补充:

(最多只允许输入30个字)