首页 > 代码库 > cocos2dx 3.2 Touch Listen和menu回调实现截屏

cocos2dx 3.2 Touch Listen和menu回调实现截屏

 

  在Cocos2d-X 3.x里面,已经集成了截屏功能,单独放在utils命名空间里,实现在base/ccUtils.h文件里面。看下函数申明

  

/** Capture the entire screen     * To ensure the snapshot is applied after everything is updated and rendered in the current frame,     * we need to wrap the operation with a custom command which is then inserted into the tail of the render queue.     * @param afterCaptured, specify the callback function which will be invoked after the snapshot is done.     * @param filename, specify a filename where the snapshot is stored. This parameter can be either an absolute path or a simple     * base filename ("hello.png" etc.), don‘t use a relative path containing directory names.("mydir/hello.png" etc.)     * @since v3.2     */
    简单看下,就是自定义一个渲染命令,加入到渲染队列尾部。
    函数参数有两个,,第一个是截屏完成后的操作函数回调,一个事自定义的截屏图片名字。
    回调函数有两个固定参数,一个是 bool型,用来判断截屏是否成功,另外一个是filename,实际上就是第二个参数会传入该回掉函数。
void captureScreen(const std::function<void(bool, const std::string&)>& afterCaptured, const std::string& filename);

  有一个很重要的问题就是:上面函数的参数filename需要加上图片格式,例如:screenshot.png。因为,在函数实现内部使用过后缀来确定保存类型的,这个略坑,建议使用jpg,毕竟图片会小很多。

  我的工程是直接用的helloword,在helloscene上添加一个label,用来做截屏点击按钮,效果如图:

  技术分享

 

  现在呢,对于Capture这个label来说,我们有两种方法给他添加响应函数,

  1、把这个label加入menu,这样可以很简单的添加回掉函数,这种方法很通用,就不细说了。

  2、另一种就是使用触摸点击来给这个label添加响应函数。

 

  首先,需要添加一个aftercapture函数,在这个函数里面呢,将截屏的图片显示出来,具体做法就是重新创建一个scene,将图片放上去,通过导演切换到这个scene。看代码:

void HelloWorld::afterCaptureScreen(bool issuccess, const std::string &filename) //这个函数参数是固定的,不能写错了{    auto size = Director::getInstance()->getWinSize();    if (issuccess)    {        auto scene = Scene::create();        auto sp = Sprite::create(filename);                sp->setScale(0.8f);        sp->setPosition(Vec2(size.width/2, size.height/2));        scene->addChild(sp);        auto lb = LabelTTF::create();        lb->setString("capture success!");        lb->setColor(ccc3 (255, 0, 0));        lb->setFontSize(40);        lb->setAnchorPoint(Vec2(0.5f, 1.0f));        lb->setPosition(Vec2(size.width/2, size.height));        scene->addChild(lb);        Director::getInstance()->replaceScene(scene);    }    else    {        auto scene = Scene::create();        auto lb = Label::create();        lb->setString("Capture Failed");        lb->setTextColor(ccc4(255, 0, 0, 255));        lb->setPosition(Vec2(size.width / 2, size.height/2));        scene->addChild(lb);        Director::getInstance()->replaceScene(scene);    }}

  接下来再添加一个函数,用于在在Capture这个label的touch ended里面调用,代码如下:

void HelloWorld::capturesc(std::string &filename){    Director::getInstance()->getTextureCache()->removeTextureForKey(filename); //这里最好加上这句,因为如果你需要重复点击这个按钮进行截屏操作的话,TextureCache里面不清除,会导致截屏失败    utils::captureScreen(CC_CALLBACK_2(HelloWorld::afterCaptureScreen, this), filename); //在这里调用cocos2d已经实现好的captureScreen函数,将我们写好的aftercapture函数和我们需要的图片名称穿进去,图片名称的初始化必须在这个函数调用之前完成}

  最后完成label触摸事件写好就OK了,当然,lambda表达式用上:

auto *ev = EventListenerTouchOneByOne::create();    //filename = "capturesc.png"; //filename可以在这里初始化    ev->onTouchBegan = [](Touch* t, Event* e){        cocos2d::log("touch begin!");        return true;    };    ev->onTouchMoved = [](Touch* t, Event* e){};    ev->onTouchEnded = [&,caplb](Touch* t, Event* e){        auto pos = t->getLocation();        auto rect = caplb->getBoundingBox();        auto cpos = caplb->convertToNodeSpace(pos);        if (rect.containsPoint (cpos))        {            cocos2d::log("caplb is touched!!");            filename = "scpic.jpg"; //初始化filename,后缀很重要            caplb->setVisible(false);//将Capture这个label隐藏            capturesc(filename); //截屏        }    };

这段代码写在HelloWord的init函数里面。

  这样就完成了,截屏操作,相对于2.x的截屏好像简单了,这个就仁者见仁智者见智了。在2.x版本里面的截屏操作需要注意的是再创建Render的时候,需要传入渲染颜色深度,否则会导致visit函数渲染时无法正确进行各个对象之间的遮挡关系计算,看下最后的效果图:

技术分享

 

 

  

cocos2dx 3.2 Touch Listen和menu回调实现截屏