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