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 };
View Code

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 }
View Code

如下是调用上面的函数

        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里面可能不止这些图片。这样子封装的类扩展性更强。

posted @ 2020-04-27 22:34  LCAC  阅读(572)  评论(0编辑  收藏  举报