【Cocos2dx】用当前游戏状态作为暂停背景、纯文字纯图片按钮与不间断的重复动作序列

前端之家收集整理的这篇文章主要介绍了【Cocos2dx】用当前游戏状态作为暂停背景、纯文字纯图片按钮与不间断的重复动作序列前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

在《【Cocos2dx】使用CCControlButton创建按钮、按钮点击事件,点击事件中的组件获取,setPosition的坐标问题》(点击打开链接)已经介绍过Cocos2dx的按钮,怎么用CCScale9Sprite与CCControlButton实现,然而这样的按钮必须要有文字图片配合起来才能够实现,有时我们只需要一个文字按钮,或者纯图片按钮。

同时,虽然在《【Cocos2dx】利用导演类、场景类完成重新开始游戏、暂停游戏、关闭游戏功能》(点击打开链接)中已经介绍过Cocos2dx的暂停功能怎么实现,但是这样的暂停画面,一片黑白,就放一个按钮实在是难看,一般别人的暂停画面都是拥有当前游戏画面的淡化背景。

下面,就用一个小例子说明这个问题:


如上图,在HelloWorld场景,放上一个官方自带的Helloworld.png,设置一个Pause文字按钮在主页上不停上下运动,点击这个Pause文字按钮就会来到PauseScene这个暂停画面,PauseScene的背景构成就是当前Helloworld的游戏状态。

这个Cocos2dx的文件结构图如下:


首先是HelloWorldScene.h,一些简单的声明:

#include "cocos2d.h"
#include "PauseScene.h"//暂停要切到这个场景,因此必须有这句
USING_NS_CC;//一旦在头文件声明用到了CC,就必须有这句
class HelloWorld : public cocos2d::CCLayer
{
public:
	virtual bool init();  
	static cocos2d::CCScene* scene();
	CREATE_FUNC(HelloWorld);
private:
	void pause(CCObject* pSender);//暂停的按钮事件
};

之后是HelloWorldScene.cpp,这里包含三个部分。

(1)纯文字图片按钮的创建。

对于纯文字按钮,是要先创建文字,再根据此文字创建菜单项,再将菜单添加菜单,最后再把菜单放到问题。此菜单仅一个菜单项,等于就是一个文字按钮。暂时没找到更好的,创建纯文字,不带图片的按钮的方法

图片按钮,则比较简单,可以与纯文字按钮的创建一样,无须为此图片先创建经历,直接对菜单项指明按下、不按下的两张图片即可。

此处对比与CCScale9Sprite与CCControlButton,组合文字图片的按钮创建。

(2)不间断的重复动作序列

不间断的重复动作序列是创建两个分动作之后,先用CCSequence将它们组合起来,再利用CCRepeatForever将其转化为一个CCFiniteTimeAction动作,给组件运行。

关于动作序列在《【Cocos2dx】基本动作、动作序列与动作合并》(点击打开链接)已经说过了,这里只是进一步深化而已。

(3)关于用当前游戏状态作为暂停背景

在当前的场景,先要用CCRenderTexture遍历当前的场景,创建纹理。

#include "HelloWorldScene.h"

CCScene* HelloWorld::scene()//场景的创建,Cocos2dx要求层必须放在场景中
{
	CCScene *scene = CCScene::create();
	HelloWorld *layer = HelloWorld::create();
	scene->addChild(layer);
	return scene;
}

bool HelloWorld::init()//层的初始化函数。
{ 
	CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();//获取当前层的尺寸

	//创建一个背景精灵
	CCSprite* background=CCSprite::create("Helloworld.png");
	background->setPosition(ccp(visibleSize.width/2,visibleSize.height/2));
	this->addChild(background,0);//添加到场景,将其置于底部,z-index为0。

	//创建一个纯文字按钮
	CCLabelTTF *label1=CCLabelTTF::create("=Pause=","Arial",24);//先创建一个文字标签文本label)

	CCMenuItemLabel *menu_item_label1=CCMenuItemLabel::create(label1,this,menu_selector(HelloWorld::pause));
	//创建一个文字菜单项,其中第1个参数是显示文字,最后一个参数是声明按钮的回调(执行)函数。
	//如果,要创建一个纯图片的按钮,则同样先创建一个图片菜单项,用CCMenuItemImage *pCloseItem=CCMenuItemImage::create("CloseNormal.png","CloseSelected.png",menu_selector(Scene1::menuGoToHelloworld));
	//这在官方自带的Helloworld就已经有,
	//在CCMenuItemImage中,第1个参数是正常状态的图片,第2个参数是被点击的图片,最后一个参数是声明按钮的回调(执行)函数。

	CCMenu* menu1=CCMenu::create(menu_item_label1,NULL);//创建一个菜单,此菜单包含menu_item_label1这个菜单项,NULL是一定要有的。
	menu1->setPosition(ccp(visibleSize.width/2,visibleSize.height/2));//菜单的位置,只能设置菜单的位置来定位,设置菜单项的位置是不使用的
	//同时补充一句,Cocos2dx中菜单是没有中心点,因此menu1->setAnchorPoint(ccp(0,1));之类的不适用
	this->addChild(menu1,1);//添加到场景,z-index为1。

	//为上面的菜单创建一段连续、不间断、重复的动作序列
	CCFiniteTimeAction* action1=CCMoveBy::create(3.0f,ccp(0,100));//在3秒内提升100px 
	CCFiniteTimeAction* action2=CCMoveBy::create(3.0f,-100));//在3秒内下降100px
	CCFiniteTimeAction* repeat_action=CCRepeatForever::create(CCSequence::create(action1,action2,NULL));//这个动作无限重复
	menu1->runAction(repeat_action);//菜单运行这个动作

	return true;
}

void HelloWorld::pause(CCObject* pSender)//暂停按钮函数
{
	CCSize visibleSize=CCDirector::sharedDirector()->getVisibleSize();//获取当前层的尺寸

	CCRenderTexture *renderTexture=CCRenderTexture::create(visibleSize.width,visibleSize.height);//通过CCRenderTexture保存当前界面(相当于截屏),然后传递给暂停界面,当成背景精灵 
	renderTexture->begin();//渲染开始
	this->getParent()->visit();//遍历整个场景的组件,通通都会被保存到CCRenderTexture中
	renderTexture->end();//渲染结束

	CCDirector::sharedDirector()->pushScene(PauseScene::scene(renderTexture));//将游戏界面暂停,压入场景堆栈。并切换到GamePause界面
}

Helloworld这个场景弄完了,接下来完成PauseScene这个场景。

首先是PauseScene.h,对比与HelloWorldScene.h这个普通场景,PauseScene.h的scene()场景初始化函数修改过的。

#include "cocos2d.h"
//将此场景出栈的时候,自动找到栈最底部的Helloworld,因此无须声明#include "HelloWorldScene.h"
USING_NS_CC;//一旦在头文件声明用到了CC,就必须有这句
class PauseScene:public cocos2d::CCLayer
{
public:
    virtual bool init();  
    static cocos2d::CCScene* scene(CCRenderTexture* renderTexture);//修改过的场景场景函数
    CREATE_FUNC(PauseScene);
private:
	void back(CCObject* pSender);//返回Helloworld场景的按钮事件
};

最后是PauseScene.cpp:
#include "PauseScene.h"

CCScene* PauseScene::scene(CCRenderTexture* renderTexture)//收到在HelloWorldScene创建的纹理renderTexture
{
	CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();//获取当前尺寸
	CCScene *scene = CCScene::create();//创建场景

	//根据纹理renderTexture创建此场景背景精灵background
	CCSprite* background=CCSprite::createWithTexture(renderTexture->getSprite()->getTexture());
	background->setPosition(ccp(visibleSize.width/2,visibleSize.height/2));//此精灵居中
	background->setFlipY(true);//垂直翻转此精灵
	background->setColor(ccGRAY);//此精灵灰色显示,也就是蒙上一层灰色膜
	scene->addChild(background);  

	PauseScene *layer = PauseScene::create();//创建层
	scene->addChild(layer);
	return scene;
}

bool PauseScene::init()//层的初始化
{
	CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();//获取当前尺寸
	//创建一个纯文字按钮
	CCLabelTTF* label1 =CCLabelTTF::create("=Back=",24);
	CCMenuItemLabel* menu_item_label1 = CCMenuItemLabel::create(label1,menu_selector(PauseScene::back));
	CCMenu* menu1 = CCMenu::create(menu_item_label1,NULL);  
	//menu1->setAnchorPoint(ccp(1,0));不适用于CCMenu,中心点默认在中央,因此只能利用加加减减摆好精灵的位置-_-!
	menu1->setPosition(ccp(visibleSize.width-menu_item_label1->getContentSize().width/2,0+menu_item_label1->getContentSize().height));//按钮的位置
	this->addChild(menu1);  
	return true;
}

void PauseScene::back(CCObject* pSender)
{
	CCDirector::sharedDirector()->popScene();//本场景出栈 
}

这里可能有人疑惑,为何创建的背景精灵涉及到垂直翻转的问题。

这是因为不垂直翻转不行,会变成如下的效果


大概Cocos2dx在Helloworld这个场景遍历该场景的所有节点的时候,是从后开始遍历的。

猜你在找的Cocos2d-x相关文章