使用的方法是: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;
}
原文链接:https://www.f2er.com/cocos2dx/339115.html