如何暂停游戏

在cocos2d-x中,Director类自带pause()方法用来暂停整个游戏,相应的resume()方法用来返回游戏。但当我们使用pause()方法时却会让游戏显得很卡,有时即使resume了,游戏还是会卡。而且现在大多数游戏在按暂停键的时候都会弹出一个Resume的Scene用来提示玩家一些信息,并且带有一个Resume按钮用来点击返回游戏。结合这两点,这里采用另外一种策略来暂停游戏。

1.      取得点击暂停那一瞬间的屏幕截屏

2.      创建一个ResumeScene, 在ResumeScene上加入获得的截屏

3.      在ResumeScene上加上一个不可碰触的,黑色半透明的ColorLayer用来阻拦用户的操作。

4.      在ResumeScene上加上一个Resume按钮用来返回游戏。

 

1.      取得点击暂停那一瞬间的屏幕截屏

3.0的截屏和2.x的截屏基本上相同,都是利用RenderTexture来处理,在渲染之前调用call函数,然后调用Cocos的场景visit函数对其进行渲染,渲染结束后调用end函数即可。只是3.0截屏需要在截完屏的下一帧才能处理RenderTexture,这点要注意。

在这里我们另外写一个工具类ScreenShoter

void ScreenShoter::saveScreenshot( const std::string& fileName, const std::function< void ( const std::string& ) >& callback ) {
	Image::Format format;
	//进行后缀判断
	if(std::string::npos != fileName.find_last_of(".")){
		auto extension = fileName.substr(fileName.find_last_of("."),fileName.length());
		if (!extension.compare(".png")) {
			format = Image::Format::PNG;
		} else if(!extension.compare(".jpg")) {
			format = Image::Format::JPG;
		} else{
			CCLOG("cocos2d: the image can only be saved as JPG or PNG format");
			return;
		}
	} else {
		CCLOG("cocos2d: the image can only be saved as JPG or PNG format");
		return ;
	}
	//获取屏幕尺寸,初始化一个空的渲染纹理对象
	auto director = Director::getInstance();
	auto renderTexture = RenderTexture::create( director->getWinSize().width, director->getWinSize().height, Texture2D::PixelFormat::RGBA8888);
	//清空并开始获取
	renderTexture->beginWithClear(0.0f, 0.0f, 0.0f, 0.0f);
	//遍历场景节点对象,填充纹理到RenderTexture中
	director->getRunningScene()->visit();
	//结束获取
	renderTexture->end();
	//保存文件
	renderTexture->saveToFile(fileName , format);

	//3.0截屏需要在截完屏的下一帧才能处理RenderTexture
	//使用schedule在下一帧中调用callback函数
	auto fullPath = FileUtils::getInstance()->getWritablePath() + fileName;
	auto scheduleCallback = [&,fullPath,callback](float dt){
		callback(fullPath);
	};
	auto _schedule = director->getRunningScene()->getScheduler();
	_schedule->schedule(scheduleCallback, director, 0.0f,0,0.0f, false, "screenshot");
}

2.     创建一个ResumeScene, 在ResumeScene上加入获得的截屏

我们在按钮的callBack函数中调用此函数即可 :

void OptionLayer::pauseBtnCallBack( Ref* ref ) {
	auto callback = [&]( const std::string& fullPath ) {
		auto screenShotSprite = Sprite::create( fullPath );
		auto resumeScene = ResumeScene::create();
		resumeScene->setBackground( screenShotSprite );
		//将Scene转变为ResumeScene
		Director::getInstance()->replaceScene( resumeScene );
	};

	ScreenShoter::saveScreenshot( "screenShot.png", callback );
}

3.     在ResumeScene的setBackground方法中加上一个不可碰触的,黑色半透明的ColorLayer,用来阻拦用户的操作。

void ResumeScene::setBackground( Sprite* iBackground ) {
	auto winSize = Director::getInstance()->getWinSize();
	this->resumeLayer = Layer::create();
	this->addChild( resumeLayer );
	iBackground->setPosition( winSize.width / 2, winSize.height / 2 );
	this->resumeLayer->addChild( iBackground );
}

4.     在ResumeScene的init()方法中便可以加入Resume按钮,只用设置Zorder优先级为3即可。

总结:

通过简单的几步就可以做出一个效果相当不错的暂停效果,但由于RenderTexture在截屏后需要在下一帧才能处理Texture,在按下暂停按钮到进入ResumeScene之间有一帧的延迟,对于大多数游戏都是可以接受的。



你可能感兴趣的:(Cocos2d-x3.0,cocos2d-x,pause)