【Cocos2dx】利用導演類、場景類完成重新開始遊戲、暫停遊戲、關閉遊戲功能
重新開始遊戲、暫停遊戲、關閉遊戲是絕對是遊戲的基礎,雖然程式碼不多,不過這要利用到Cocos2dx導演類、場景類完成,事先如果不對其進行了解,絕對是很難做出來。
下面用一個小例子說明如何利用導演類、場景類完成重新開始遊戲、暫停遊戲、關閉遊戲功能,
這個被改寫的HelloWorld場景,一開始就宣告一個在螢幕中央開始5s內上升100px的按鈕精靈,
可以看到,點選左上角的Refresh!按鈕,這個場景的所有動作會重新開始,也就是,將HelloWorld場景銷燬,重新執行HelloWorld場景的init()函式,相當於“重新開始遊戲”。
點選右上角的Pause!按鈕會儲存當前HelloWorld場景的所有操作,來到一個新的Pause場景,點選其中的Back!按鈕,會重新返回HelloWorld場景,按鈕精靈會繼續執行在螢幕中央開始5s內上升100px的動作,而不是重新開始,相當於"暫停遊戲"。
"關閉遊戲"在官方的Helloworld已經有,不過涉及這裡的相關的知識,也在這裡說說。
工程的檔案結構如下:
“暫停遊戲”必須新建一個帶“返回”按鈕場景,不新建這個暫停場景,是做不出來,雖然新建場景是一件複雜的事情,但你不這樣做,是搞不出來的。
關於場景的概念在《【Cocos2dx】新建場景、場景的切換、設定啟動場景與選單的新建》(點選開啟連結)已經講過了,但這裡著重對場景的scene函式的重寫,這個scene函式相當於場景新建時候執行的建構函式。
先看改寫了的HelloWorldScene:
HelloWorldScene.h,一些宣告,沒什麼好說,只是刪除一些官方無用的預編譯宣告、註釋:
HelloWorldScene.cpp,看起來程式碼很長很長,然而在init()宣告N個按鈕起始是一大堆重複的,詳情可以看《【Cocos2dx】使用CCControlButton建立按鈕、按鈕點選事件,點選事件中的元件獲取,setPosition的座標問題 》(點選開啟連結),關鍵是各個函式的回撥函式,核心是你要通過CCDirector::sharedDirector()召喚出導演,才能操作場景:#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);//關閉 };
#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!","arial",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!","arial",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!","arial",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();
}