重新开始游戏、暂停游戏、关闭游戏是绝对是游戏的基础,虽然代码不多,不过这要利用到Cocos2dx导演类、场景类完成,事先如果不对其进行了解,绝对是很难做出来。
下面用一个小例子说明如何利用导演类、场景类完成重新开始游戏、暂停游戏、关闭游戏功能,
这个被改写的HelloWorld场景,一开始就声明一个在屏幕中央开始5s内上升100px的按钮精灵,
可以看到,点击左上角的Refresh!按钮,这个场景的所有动作会重新开始,也就是,将HelloWorld场景销毁,重新执行HelloWorld场景的init()函数,相当于“重新开始游戏”。
点击右上角的Pause!按钮会保存当前HelloWorld场景的所有操作,来到一个新的Pause场景,点击其中的Back!按钮,会重新返回HelloWorld场景,按钮精灵会继续执行在屏幕中央开始5s内上升100px的动作,而不是重新开始,相当于"暂停游戏"。
"关闭游戏"在官方的Helloworld已经有,不过涉及这里的相关的知识,也在这里说说。
工程的文件结构如下:
“暂停游戏”必须新建一个带“返回”按钮场景,不新建这个暂停场景,是做不出来,虽然新建场景是一件复杂的事情,但你不这样做,是搞不出来的。
关于场景的概念在《【Cocos2dx】新建场景、场景的切换、设置启动场景与菜单的新建》(点击打开链接)已经讲过了,但这里着重对场景的scene函数的重写,这个scene函数相当于场景新建时候执行的构造函数。
先看改写了的HelloWorldScene:
HelloWorldScene.h,一些声明,没什么好说,只是删除一些官方无用的预编译声明、注释:
#include "cocos2d.h" #include "cocos-ext.h" //使用按钮事件,必须要需要的头文件 USING_NS_CC_EXT;//使用按钮事件,必须要需要的命名空间 class HelloWorld:public cocos2d::CCLayer { public: virtual bool init();//场景初始化的函数 //场景声明函数 static cocos2d::CCScene* scene(); CREATE_FUNC(HelloWorld); void pause(CCObject* pSender,CCControlEvent event);//暂停 void restart(CCObject* pSender,CCControlEvent event);//重新开始 void close(CCObject* pSender,CCControlEvent event);//关闭 };HelloWorldScene.cpp,看起来代码很长很长,然而在init()声明N个按钮起始是一大堆重复的,详情可以看《【Cocos2dx】使用CCControlButton创建按钮、按钮点击事件,点击事件中的组件获取,setPosition的坐标问题》( 点击打开链接),关键是各个函数的回调函数,核心是你要通过CCDirector::sharedDirector()召唤出导演,才能操作场景:
#include "HelloWorldScene.h" #include "PauseScene.h" USING_NS_CC; CCScene* HelloWorld::scene() { CCScene *scene = CCScene::create();//创建HelloWorld场景 HelloWorld *layer = HelloWorld::create();//创建HelloWorld层 scene->addChild(layer);//将HelloWorld层放在HelloWorld场景,所有元素只能放在层上,而不能放在场景上,场景仅能放层,相当于JavaSwing中在frame中添加panel才能继续搞 return scene; } bool HelloWorld::init() { //获取屏幕的尺寸、位置信息等 CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize(); //声明按钮部分 /*右上角按钮*/ CCScale9Sprite *btn_noraml1 = CCScale9Sprite::create("CloseNormal.png");//声明CloseNormal图片,用于按钮没被按下时的背景图片 CCLabelTTF *label1 = CCLabelTTF::create("Pause!","arial",36);//声明一个文字Pause!第2个参数是字体,仅能使用Resource文件夹中fonts文件夹中的字体,第3个参数是字体大小 CCControlButton *controlButton1 = CCControlButton::create(label1,btn_noraml1); controlButton1->setAnchorPoint(ccp(1,1)); controlButton1->setPosition(ccp(visibleSize.width,visibleSize.height)); controlButton1->addTargetWithActionForControlEvents(this,cccontrol_selector(HelloWorld::pause),CCControlEventTouchDown);//声明按钮的事件,第三个参数为定值常量意为,点击此按钮之后,触发第二个函数所声明的,下面给出的HelloWorld::pause(){}中所有代码。 this->addChild(controlButton1);//将此按钮添加到场景,默认不自动添加 /*左上角按钮*/ CCScale9Sprite *btn_noraml2 = CCScale9Sprite::create("CloseNormal.png");//声明CloseNormal图片,用于按钮没被按下时的背景图片 CCLabelTTF *label2 = CCLabelTTF::create("Refresh!",36);//声明一个文字Refresh!第2个参数是字体,仅能使用Resource文件夹中fonts文件夹中的字体,第3个参数是字体大小 CCControlButton *controlButton2 = CCControlButton::create(label2,btn_noraml2); controlButton2->setAnchorPoint(ccp(0,1)); controlButton2->setPosition(ccp(0,visibleSize.height)); controlButton2->addTargetWithActionForControlEvents(this,cccontrol_selector(HelloWorld::restart),CCControlEventTouchDown);//声明按钮的事件,第三个参数为定值常量意为,点击此按钮之后,触发第二个函数所声明的,下面给出的HelloWorld::restart(){}中所有代码。 this->addChild(controlButton2);//将此按钮添加到场景,默认不自动添加 /*右下角按钮*/ CCScale9Sprite *btn_noraml3 = CCScale9Sprite::create("CloseNormal.png");//声明CloseNormal图片,用于按钮没被按下时的背景图片 CCLabelTTF *label3 = CCLabelTTF::create("Close!",36);//声明一个文字Close!第2个参数是字体,仅能使用Resource文件夹中fonts文件夹中的字体,第3个参数是字体大小 CCControlButton *controlButton3 = CCControlButton::create(label3,btn_noraml3); controlButton3->setAnchorPoint(ccp(1,0)); controlButton3->setPosition(ccp(visibleSize.width,0)); controlButton3->addTargetWithActionForControlEvents(this,cccontrol_selector(HelloWorld::close),CCControlEventTouchDown);//声明按钮的事件,第三个参数为定值常量意为,点击此按钮之后,触发第二个函数所声明的,下面给出的HelloWorld::close(){}中所有代码。 this->addChild(controlButton3);//将此按钮添加到场景,默认不自动添加 /*声明一个做动作的按钮精灵,以显示出效果*/ CCSprite *sprite=CCSprite::create("CloseSelected.png"); sprite->setPosition(ccp(visibleSize.width/2,visibleSize.height/2)); this->addChild(sprite); CCFiniteTimeAction* action2=CCMoveBy::create(5.0f,ccp(0,100));//在5秒内提升100px sprite->runAction(action2); return true; } void HelloWorld::pause(CCObject* pSender,CCControlEvent event) { //将游戏界面暂停,压入场景堆栈。并切换到GamePause界面 CCDirector::sharedDirector()->pushScene(PauseScene::scene()); } void HelloWorld::restart(CCObject* pSender,CCControlEvent event) { //将游戏界面重新开始,replaceScene意思是用一个新场景替换旧场景,旧场景被替换之后,马上被销毁 CCDirector::sharedDirector()->replaceScene(HelloWorld::scene()); } void HelloWorld::close(CCObject* pSender,CCControlEvent event) { //结束当前游戏 CCDirector::sharedDirector()->end(); exit(0); }
之后是暂停场景类PauseScene,
PauseScene.h同样是一些声明:
#include "cocos2d.h" #include "cocos-ext.h" //使用按钮事件,必须要需要的头文件 USING_NS_CC_EXT;//使用按钮事件,必须要需要的命名空间 using namespace cocos2d; class PauseScene:public CCLayer{ public: static CCScene* scene(); virtual bool init(); CREATE_FUNC(PauseScene); void back(CCObject* pSender,CCControlEvent event);//返回场景 };
PauseScene.cpp则同样是放一个按钮,按钮的回调函数,同样是召唤出Cocos2dx的导演。
暂停功能是这样的:Cocos2dx自身就自带一个场景栈,在初始化的时候,在main.cpp指定的开始场景就会自动进入场景栈,具体见《【Cocos2dx】Windows平台下Cocos2dx 2.x的下载、安装、配置,打造自己的Helloworld》(点击打开链接),暂停的话,CCDirector::sharedDirector()召唤出来的导演,有令让某一场景进入场景栈的方法pushScene,Cocos2dx只会演出当前在场景栈最上方的场景,下方的所有场景的行为、元素位置,通通会被存档、暂停,待其回到场景栈最顶部才会继续运行。
导演同样有让当前在场景栈最上方的场景出栈的方法。场景被出栈是马上被销毁,再也找不到了。
如果场景栈为空,则会自动关闭游戏,不过建议还是用导演的end()与exit(0)方法来结束游戏,这也是Cocos2dx官方的Helloworld使用的方法。
#include "PauseScene.h" USING_NS_CC; CCScene* PauseScene::scene() { CCScene *scene=CCScene::create(); PauseScene* pauseScene=PauseScene::create(); scene->addChild(pauseScene); return scene; } bool PauseScene::init() { //获取屏幕的尺寸、位置信息等 CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize(); //声明按钮部分 cocos2d::extension::CCScale9Sprite *btn_noraml = cocos2d::extension::CCScale9Sprite::create("CloseNormal.png");//声明CloseNormal图片,用于按钮没被按下时的背景图片 CCLabelTTF *label1 = CCLabelTTF::create("back!",36);//声明一个文字Click me!第2个参数是字体,仅能使用Resource文件夹中fonts文件夹中的字体,第3个参数是字体大小 CCControlButton *controlButton = CCControlButton::create(label1,btn_noraml); controlButton->setPosition(ccp(visibleSize.width/2,visibleSize.height/2));//按钮的中心点位于屏幕的中央 controlButton->addTargetWithActionForControlEvents(this,cccontrol_selector(PauseScene::back),CCControlEventTouchDown);//声明按钮的事件,第三个参数为定值常量意为,点击此按钮之后,触发第二个函数所声明的,下面给出的PauseScene::back(){}中所有代码。 this->addChild(controlButton);//将此按钮添加到场景,默认不自动添加 return true; } void PauseScene::back(CCObject* pSender,CCControlEvent event) { //本场景出栈 CCDirector::sharedDirector()->popScene(); }