cocos2dx 第六章 图片导入
1、CCSpriteBatchNode
该方式适用在导入多张一样的图片时候的优化。
CCSpriteBatchNode* batchNode = CCSpriteBatchNode::create("sprite.png"); this->addChild(batchNode); bool bRet = false; do { for (int i = 0; i < 100000; ++i) { CCSprite* xiaoruo = CCSprite::create("sprite.png"); xiaoruo->setPosition(ccp(CCRANDOM_0_1() * 1000, CCRANDOM_0_1() * 640)); batchNode->addChild(xiaoruo); } } while (false);
如上所示,先创建要导入的图片的CCSpriteBatchNode;
然后将该精灵加入图层中。接下去创建相同的精灵图片之后,都加到CCSpriteBatchNode里面。则能实现优化。具体优化是opengl底层做的事。
2、createWithSpriteFrame
通过该方式创建的精灵,当另外精灵使用该创建对应的图片时候则也会在绘制上实现优化。
CCSprite* sp1 = CCSprite::createWithSpriteFrame(CCSpriteFrame::create("sprite.png", CCRectMake(0, 0, 60, 50))); CCSprite* sp2 = CCSprite::create("sprite.png"); sp1->setPosition(ccp(100, 200)); sp2->setPosition(ccp(250, 200)); this->addChild(sp1); this->addChild(sp2); CCTexture2D* t1 = sp1->getTexture(); CCTexture2D* t2 = sp2->getTexture();
如上t1跟t2是两个相同的texture,因为指针的地址是一样的。
3、绘制动画
在说绘制动画之前先了解一下.plist配置文件。该配置文件是一种图片的列表。因为当多张图片组合到一张图片,然后通过CCSpriteFrameCache进行载入,程序底层的opengl会对图片的显示等进行优化,所以使用多张图片组合到一张图片的方式。然后用.plist指出每张图片的位置。.plist 文件是通过图片打包软件生成的。作者推荐了TexturePacker这款软件。
原文给出了两种方式绘制动画。这里只给出一种比较优秀的方式
CCAnimate* HelloWorld::createAnimate2() { CCSpriteFrameCache* frameCache = CCSpriteFrameCache::sharedSpriteFrameCache(); frameCache->addSpriteFramesWithFile("boys.plist", "boys.png"); int iFrameNum = 15; CCSpriteFrame* frame = NULL; CCArray* frameArray = CCArray::create(); for (int i = 1; i <= iFrameNum; ++i) { frame = frameCache->spriteFrameByName(CCString::createWithFormat("run%d.png", i)->getCString()); frameArray->addObject(frame); } CCAnimation* animation = CCAnimation::createWithSpriteFrames(frameArray); animation->setLoops(-1); animation->setDelayPerUnit(0.1f); CCAnimate* action = CCAnimate::create(animation); return action; }
如上先通过plist创建了原始图片,然后通过
1、frameCache->spriteFrameByName创建原始图片里面需要用到的图片。图片名称则在plist里面。一般是你组合之前的图片的名字。
2、CCAnimation* animation创建图片组合列表。这些组合以指定的时间间隔顺序播放。给人感觉图片在动。
记得要设置时间间隔,否则无法看到图片是否在切换。
最后返回对应的action。然后执行runAction即可
CCSprite* runSp = CCSprite::create("run1.png"); runSp->setPosition(ccp(100, 200)); this->addChild(runSp); runSp->runAction(createAnimate2());
笔者在最后给出了一个显示动画的通用方式
AnimationUtil.h
1 #pragma once 2 #include "cocos2d.h" 3 USING_NS_CC; 4 5 class AnimationUtil 6 { 7 public: 8 AnimationUtil(); 9 ~AnimationUtil(); 10 11 static CCAnimation* createAnimWithSingleFrameN(const char* name, float delay, unsigned int iLoops); 12 static CCAnimation* createAnimWithFrameNameAndNum(const char* name, int iNum, float delay, unsigned int iLoops); 13 };
AnimationUtil.cpp
1 #include "AnimationUtil.h" 2 3 4 AnimationUtil::AnimationUtil() 5 { 6 } 7 8 9 AnimationUtil::~AnimationUtil() 10 { 11 } 12 13 CCAnimation* AnimationUtil::createAnimWithSingleFrameN(const char* name, float delay, unsigned int iLoops) 14 { 15 CCSpriteFrameCache* cache = CCSpriteFrameCache::sharedSpriteFrameCache(); 16 CCArray* framesArray = CCArray::create(); 17 CCSpriteFrame* frame = NULL; 18 int index = 1; 19 do 20 { 21 frame = cache->spriteFrameByName(CCString::createWithFormat("%s%d.png", name, index++)->getCString()); 22 if (frame == NULL) 23 break; 24 framesArray->addObject(frame); 25 } while (true); 26 27 CCAnimation* animation = CCAnimation::createWithSpriteFrames(framesArray); 28 animation->setLoops(iLoops); 29 animation->setDelayPerUnit(delay); 30 animation->setRestoreOriginalFrame(true); 31 32 return animation; 33 } 34 35 CCAnimation* AnimationUtil::createAnimWithFrameNameAndNum(const char* name, int iNum, float delay, unsigned int iLoops) 36 { 37 CCSpriteFrameCache* cache = CCSpriteFrameCache::sharedSpriteFrameCache(); 38 CCArray* frameArray = CCArray::create(); 39 40 CCSpriteFrame* frame = NULL; 41 int index = 1; 42 for (int i = 1; i <= iNum; ++i) { 43 frame = cache->spriteFrameByName(CCString::createWithFormat("%s%d.png", name, index++)->getCString()); 44 if (frame == NULL) 45 break; 46 frameArray->addObject(frame); 47 } 48 49 CCAnimation* animation = CCAnimation::createWithSpriteFrames(frameArray); 50 animation->setLoops(iLoops); 51 animation->setRestoreOriginalFrame(true); 52 animation->setDelayPerUnit(delay); 53 54 return animation; 55 }
如下是调用上面的函数
CCSprite* runSp = CCSprite::create("run1.png"); runSp->setPosition(ccp(100, 200)); this->addChild(runSp); CCSpriteFrameCache* frameCache = CCSpriteFrameCache::sharedSpriteFrameCache(); frameCache->addSpriteFramesWithFile("boys.plist", "boys.png"); //CCAnimation* animation = AnimationUtil::createAnimWithSingleFrameN("run", 0.1f, -1); CCAnimation* animation = AnimationUtil::createAnimWithFrameNameAndNum("run", 15, 0.1f, -1); runSp->runAction(CCAnimate::create(animation));
这里将图片载入CCSpriteFrameCache放在函数的外面,是因为一张plist里面可能不止这些图片。这样子封装的类扩展性更强。