CCSpriteBatchNode 和 CCTextureAtlas 详解
2013-11-28 09:54
381 查看
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 纹理图集。说白了,它本身保存一张大图的纹理和一个记录画大图某一区域的信息结构体的数组。
5 int m_uCapacity ,四边形的容量。
然后把所有用到那张大图里面的小图的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 纹理图集。说白了,它本身保存一张大图的纹理和一个记录画大图某一区域的信息结构体的数组。
5 int m_uCapacity ,四边形的容量。
相关文章推荐
- mac 下 node-qrcode的二维码库
- 关于nodejs的一些配置的小结(工作小结)
- Node.js的模块载入方式与机制
- 到底什么是inode?
- Cluster中3个Nodes挂掉2个,恢复Recovery Pending的DB的方案探索(续)
- Nodejs 基础
- Node.js的模块载入方式与机制
- Hadoop put 报异常“could only be replicated to 0 nodes, instead of 1”
- Understanding node.js
- LeetCode Remove Nth Node From End of List 删除倒数第n个元素
- 《了不起的Node.js》读后感
- leetcode: Remove Nth Node From End of List
- nodejs
- 专门针对初学者的Node.js教程
- windows下node.js安装教程图文详解
- CCNode
- [0] Node.js
- 【Node】SuperAgent
- Js中parentNode,parentElement,childNodes,children之间的区别
- NODEJS源码初探