1. 程式人生 > >【Cocos2dx】利用導演類、場景類完成重新開始遊戲、暫停遊戲、關閉遊戲功能

【Cocos2dx】利用導演類、場景類完成重新開始遊戲、暫停遊戲、關閉遊戲功能

重新開始遊戲、暫停遊戲、關閉遊戲是絕對是遊戲的基礎,雖然程式碼不多,不過這要利用到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!","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();
}