最近想找個項目練練手,苦於沒有素材,從別處找一份,但是圖片都是打包好的,很多圖片對於練手來講多余了,為了減少包體和更加靈活的使用圖片,便使用cocos2dx引擎庫把所有的散圖都截了出來。由於cocos3.x之后修改了渲染方式,所以之前用node直接visit的方式就比較難弄,於是我就選擇按照plist讀取的圖片進行遍歷渲染再使用RenderTexture保存下來。
隨便創建一個場景,我直接使用的helloword,在init函數里面將plist圖片加入SpriteFrameCache里面。
SpriteFrameCache::getInstance()->addSpriteFramesWithFile(plistname);
然后初始化幾個必須的變量,打開隨幀循環:
timer = 0; //定時器timer number = 0; //當前的圖片數量 callindex = 0;//定時器里面調用保存圖片的次數
timeadd = 0; scheduleUpdate();//打開隨幀update
update函數:
timeadd用來延時,保證當前要截取的圖片有足夠的時間渲染出來。
timer += dt; if (timer >= (callindex + 2 + timeradd)) { savefile(); timeadd += 0.2f; }
savefile函數:
auto winsize = Director::getInstance()->getWinSize(); ValueMap vm = FileUtils::getInstance()->getValueMapFromFile(plistname); ValueMap& framesDict = vm["frames"].asValueMap(); Scene *scene = Director::getInstance()->getRunningScene(); int index = 0; for (auto iter = framesDict.begin(); iter != framesDict.end(); ++iter) { if(index == numberindex) { if (callindex == numberindex * 2) { if(!prename.empty()) { if (this->getChildByName(prename)) { this->removeChildByName(prename); } } std::string spriteFrameName = iter->first; prename = spriteFrameName; auto sp = Sprite::createWithSpriteFrameName(spriteFrameName); sp->setAnchorPoint(Vec2(0, 0)); sp->setPosition(Vec2(0, 0)); sp->setName(prename); sp->setAnchorPoint(Vec2::ANCHOR_BOTTOM_LEFT); spsize = sp->getContentSize(); addChild(sp); numberindex++; break; } else{ RenderTexture* rt = RenderTexture::create(spsize.width, spsize.height); rt->begin(); scene->visit(); rt->end(); rt->saveToFile(prename, Image::Format::PNG); break; } } index++; } callindex++; if (callindex == framesDict.size()*2) { RenderTexture* rt = RenderTexture::create(spsize.width, spsize.height); rt->begin(); scene->visit(); rt->end(); rt->saveToFile(prename, Image::Format::PNG); }
從第一次開始,調用savefile進行圖片的渲染,第二次就進行圖片截取,第三次刪除上次的圖片,添加下一章圖片,第四次又進行圖片的截取,以此類推,一張一張的把plist里的圖片截取出來。