最近想找个项目练练手,苦于没有素材,从别处找一份,但是图片都是打包好的,很多图片对于练手来讲多余了,为了减少包体和更加灵活的使用图片,便使用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里的图片截取出来。