【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",this,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,ccp(0,-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=", "Arial", 24);
	CCMenuItemLabel* menu_item_label1 = CCMenuItemLabel::create(label1,this,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这个场景遍历该场景的所有节点的时候,是从后开始遍历的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值