cocos2d-x 4.0 學習之路(九)創建精靈 利用Sprite Sheet

接着上一篇,利用幀緩存來創建精靈。

尤其是做幀動畫,就更得需要這種方法來創建精靈。比如下面的骨骼動畫:

幀緩存的工作步驟是:先把所有的精靈都做成在一個文件裏,這個文件叫Sprite Sheets,是.plist文件,然後將這個文件加載到SpriteFrameCache裏面。調用的時候,直接從這個Cache裏面讀取你想顯示的精靈。

爲什麼要用Sprite Sheets?原因:

1. 節省時間。如果你一個一個的文件加載,電腦豈不是累死。

2. 分開加載的話,每個圖片在內存裏的位置都是分開的,不便於程序快速引用

3. 在紋理的形式,圖片相互轉換的話程序消耗更高

4. 精靈不能夠得到優化。比如優化成多邊形的精靈,可以節省內存。

那麼,利用Sprite Sheets你可以讓程序跑的飛快,而且用起來非常方便。那我們開始吧~

我們目標就是做一個骨骼動畫,所有的資源在這裏

第一步,做成Sprite Sheets

我們當然得需要工具,那麼官網推薦的工具是texturePacker,下載。安裝完了後,啓動界面如下:

然後,把cityscene文件夾拖進來。注意右邊需要幾個設定的地方。

點擊縮放變體,在裏面選cocos2d-x HDR/HD/SD,點擊應用,關閉設定窗口。

點擊發布精靈表,選個地方保存。

如果出現這個錯誤,是你沒有加上佔位符{v}

在數據文件裏這樣寫:.../res/{v}/cityscene.plist。再發布精靈表,成功了。

你會發現在res下,生成了3個文件夾,裏面都會有cityscene.plist。這個是針對3個不同分辨率的。

屏幕高度h<512, 用SD;513 < h < 1024,用HD;h > 1024,用HDR。

打開一個plist看一下,其實就是xml格式的內容。

第二步:導入plist到SpriteFrameCache

SpriteFrameCache::getInstance()->addSpriteFramesWithFile("cityscene.plist");

之後,我們先加載背景圖片:

// HelloWorldScene.cpp
bool HelloWorld::init()
{
    if (!Scene::init()){ return false; }

    auto visibleSize = Director::getInstance()->getVisibleSize();
    auto origin = Director::getInstance()->getVisibleOrigin();
    
    SpriteFrameCache::getInstance()->addSpriteFramesWithFile("cityscene.plist");
    // background
    auto background = Sprite::createWithSpriteFrameName("background.png");
    background->setPosition(origin.x + visibleSize.width / 2, origin.y + visibleSize.height / 2);
    this->addChild(background);
    return true;
}
// AppDelegate.cpp
    static cocos2d::Size designResolutionSize = cocos2d::Size(1024, 768);    // <-- Modify
    

    auto frameSize = glview->getFrameSize();
    std::vector<std::string> searchPaths;        // <-- Add
    // if the frame's height is larger than the height of medium size.
    if (frameSize.height > mediumResolutionSize.height)
    {        
        searchPaths.push_back("res/HDR");        // <-- Add
        director->setContentScaleFactor(MIN(largeResolutionSize.height/designResolutionSize.height, largeResolutionSize.width/designResolutionSize.width));
    }
    // if the frame's height is larger than the height of small size.
    else if (frameSize.height > smallResolutionSize.height)
    {        
        searchPaths.push_back("res/HD");        // <-- Add
        director->setContentScaleFactor(MIN(mediumResolutionSize.height/designResolutionSize.height, mediumResolutionSize.width/designResolutionSize.width));
    }
    // if the frame's height is smaller than the height of medium size.
    else
    {        
        searchPaths.push_back("res/SD");        // <-- Add
        director->setContentScaleFactor(MIN(smallResolutionSize.height/designResolutionSize.height, smallResolutionSize.width/designResolutionSize.width));
    }
    FileUtils::getInstance()->setSearchPaths(searchPaths);    // <-- Add
    register_all_packages();

第三步:加載精靈:這是一個原地走路的動畫。

// HelloWorldScene.h Add
private:
    cocos2d::Vector<cocos2d::SpriteFrame*> getAnimation(const char* format, int count);

// HelloWorldScene.cpp
// After this->addChild(background), Add the following code
    auto frames = getAnimation("capguy/walk/%04d.png", 8);
    auto sprite = Sprite::createWithSpriteFrame(frames.front());
    background->addChild(sprite);
    sprite->setPosition(100, 300);

    auto animation = Animation::createWithSpriteFrames(frames, 1.0f / 8);
    sprite->runAction(RepeatForever::create(Animate::create(animation)));

// Create New Function
Vector<SpriteFrame*> HelloWorld::getAnimation(const char* format, int count)
{
    auto spritecache = SpriteFrameCache::getInstance();
    Vector<SpriteFrame*> animFrames;
    char str[100];
    for (int i = 1; i <= count; i++)
    {
        sprintf(str, format, i);
        animFrames.pushBack(spritecache->getSpriteFrameByName(str));
    }
    return animFrames;
}

我們可以再加上移動的效果:

// HelloWorldScene.cpp
// After sprite->runAction(RepeatForever::create(Animate::create(animation))), Add following code
    auto movement = MoveTo::create(5, Vec2(1024, 300));
    auto resetPosition = MoveTo::create(0, Vec2(-75, 300));
    auto sequence = Sequence::create(movement, resetPosition, NULL);
    sprite->runAction(RepeatForever::create(sequence));

以上。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章