使用的方法是:RenderTexture渲染纹理+对当前场景的层Layer施加位移(先改后还)。
全屏截图可以使用以前的方法 RenderTexture渲染纹理,
也可以使用cocos2d::utils::captureScreen方法来完成。
保存下截图文件的话,还是需要使用到RenderTexture的saveToFile方法。
(鄙人新手一枚,如有好的方法,或者认为我这样做存在问题的,请多多指教,在此谢过了!)
代码如下:
Screen.h
- #ifndef _SCREEN_H_
- #define _SCREEN_H_
- #include "cocos2d.h"
- USING_NS_CC;
- class ScreenScene :public Layer
- {
- public:
- static Scene* createScene();
- virtual bool init();
- CREATE_FUNC(ScreenScene);
- void menuCloseCallback(Ref *pSender);
- bool onTouchBegan(Touch *touch,Event *event);
- void onTouchEnded(Touch *touch,Event *event);
- void afterCaptured(bool success,std::string fileName);
- //屏幕截图
- void screenShoot(Size size);
- private:
- //触摸起始点与结束点
- Vec2 _startPos,_endPos;
- };
- #endif
Screen.cpp
- #include "Screen.h"
- Scene* ScreenScene::createScene()
- {
- auto scene = Scene::create();
- auto layer = ScreenScene::create();
- scene->addChild(layer,0,11);
- return scene;
- }
-
- bool ScreenScene::init()
- {
- if (!Layer::init())
- {
- return false;
- }
- //获取视图
- auto visibleSize = Director::getInstance()->getVisibleSize();
- //添加背景图片
- auto bgSprite = Sprite::create("HelloWorld.png");
- bgSprite->setScale(visibleSize.width / bgSprite->getContentSize().width,visibleSize.height / bgSprite->getContentSize().height);
- bgSprite->setPosition(visibleSize.width / 2,visibleSize.height / 2);
- this->addChild(bgSprite);
-
- //添加关闭按钮
- auto closeItem = MenuItemImage::create(
- "CloseNormal.png","CloseSelected.png",CC_CALLBACK_1(ScreenScene::menuCloseCallback,this));
-
- closeItem->setPosition(visibleSize.width - closeItem->getContentSize().width / 2,closeItem->getContentSize().height / 2);
- // create menu,it's an autorelease object
- auto menu = Menu::create(closeItem,nullptr);
- menu->setPosition(Vec2::ZERO);
- this->addChild(menu,1);
-
- auto touchListener = EventListenerTouchOneByOne::create();
- touchListener->onTouchBegan = CC_CALLBACK_2(ScreenScene::onTouchBegan,this);
- touchListener->onTouchEnded = CC_CALLBACK_2(ScreenScene::onTouchEnded,this);
- _eventDispatcher->addEventListenerWithSceneGraPHPriority(touchListener,this);
-
- //this->setPosition(-20,-20);
- return true;
- }
-
- void ScreenScene::menuCloseCallback(Ref *pSender)
- {
- _director->end();
- }
-
- bool ScreenScene::onTouchBegan(Touch *touch,Event *event)
- {
- //获取起始点
- auto nodeLocation = this->convertToNodeSpace(touch->getLocation());
- _startPos = nodeLocation;
- return true;
- }
-
-
- void ScreenScene::onTouchEnded(Touch *touch,Event *event)
- {
- auto visibleSize = _director->getVisibleSize();
- auto origin = Director::getInstance()->getVisibleOrigin();
- //获得结束点
- _endPos = this->convertToNodeSpace(touch->getLocation());
- //定义一个划取大小的渲染纹理
- auto shootSize = Size(MIN(abs(_startPos.x - _endPos.x),visibleSize.width),MIN(abs(_startPos.y - _endPos.y),visibleSize.height));
- auto renderTexture = RenderTexture::create(shootSize.width,shootSize.height);
- //获取当前场景
- auto currentScene = _director->getRunningScene();
- //获取左下点
- auto LeftDownPoint = Vec2(MAX(MIN(_startPos.x,_endPos.x),0),MAX(MIN(_startPos.y,_endPos.y),0));
- auto offset = Vec2(0,0) - LeftDownPoint;
- //位移
- currentScene->getChildByTag(11)->setPosition(offset);
-
- renderTexture->beginWithClear(0.0f,0.0f,0.0f);
- currentScene->visit();
- renderTexture->end();
-
- //还原
- //这里不设置延迟的话,由于前后时间的问题,会导致截图出现大的偏差。
- auto delay = DelayTime::create(0.001f);
- auto callfunc = CallFunc::create([=]{
- //不让其还原的时候闪烁一下
- Director::getInstance()->pause();
- currentScene->getChildByTag(11)->setPosition(0,0);
- Director::getInstance()->resume();
- });
- this->runAction(Sequence::create(delay,callfunc,nullptr));
-
- //这个path是截图保存的路径。
- auto path = FileUtils::getInstance()->getWritablePath();
- renderTexture->saveToFile("ScreenShoot5201314.png",Image::Format::PNG);
- return;
-
- //这个是截取全屏的,因为上面已经return了,所以不会执行到这
- //可以把上面全部注释掉,就能够看到效果了。
- utils::captureScreen(CC_CALLBACK_2(ScreenScene::afterCaptured,this),"newScreenShoot.png");
- return;
- }
-
- //捕获之后
- void ScreenScene::afterCaptured(bool success,std::string fileName)
- {
- auto visibleSize = _director->getVisibleSize();
- if (success)
- {
- //先在中间显示,然后慢慢淡出,移除。当然还是将截图保存下来了
- auto shootSprite = Sprite::create(fileName);
- shootSprite->setScale(0.25);
- shootSprite->setPosition(visibleSize.width / 2,visibleSize.height / 2);
- this->addChild(shootSprite,1,1);
- screenShoot(shootSprite->getContentSize());
- auto delay = DelayTime::create(1.0f);
- auto fadeOut = FadeOut::create(2.0f);
- auto callFunc = CallFunc::create([=]{shootSprite->removeFromParent(); log("the sprite has removed from his parentNode!"); });
- shootSprite->runAction(Sequence::create(delay,fadeOut,callFunc,nullptr));
-
- }
- else
- {
- log("capture screen Failed!");
- }
- }
-
- void ScreenScene::screenShoot(Size size)
- {
- auto visibleSize = _director->getVisibleSize();
-
- auto renderTexture = RenderTexture::create(size.width,size.height,Texture2D::PixelFormat::RGBA8888);
- auto shootSprite = this->getChildByTag(1);
- renderTexture->beginWithClear(0,0);
- shootSprite->visit();
- renderTexture->end();
- //这个path是截图保存的路径。
- auto path = FileUtils::getInstance()->getWritablePath();
- renderTexture->saveToFile("newScreenShoot.png",Image::Format::PNG);
- return;
- }