1. 程式人生 > >分析Cocos2d-x 場景切換

分析Cocos2d-x 場景切換

本文三部分:

1.前言

2.選單按鈕執行場景切換

3.場景切換特效

1.前言

場景切換,我覺得可以分為兩種:

1)一種就是自動切換,比如玩遊戲碰到的,遊戲載入完成時的切換,這種一般有個事件觸發機制,本次暫先不講。

2)還有就是點選切換,比如點選某個按鈕,回撥函式時場景切換。

首先說一下,我們剛開始建立新的專案後,開始的HelloWorld場景是怎麼顯現出來的呢?

C++程式在執行時,首找main函式,可以發現,在新建專案中Classes裡面沒有main函式,難道Cocos2d-x沒有main函式嗎?當然...不是!

其實在win32目錄下,main.cpp和main.h

開啟main.cpp 可以看到:

#include "main.h"
#include "AppDelegate.h"
#include "cocos2d.h"
USING_NS_CC; 
int APIENTRY _tWinMain(HINSTANCE hInstance, 
HINSTANCEhPrevInstance, 
LPTSTRlpCmdLine, 
intnCmdShow) 
{ 
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// create the application instance
AppDelegate app;
returnApplication::getInstance()->run(); 
}

最上面那三行,不用多說,接下來的using namespace cocos2d。然後是Cocos2d-x的入口 APIENTRY _tWinMain。接下來,看到了建立了AppDelegate物件,然後,run函式。

暫時先說到這,感興趣的,可以跟蹤一下,看具體有什麼,怎麼執行。

在AppDelegate類中,有個函式applicationDidFinishLaunching(),這個函式是程式啟動後呼叫的函式,一般在這個函式裡建立裝置與場景。

這裡我用的以前的專案,所以建立的場景不是HelloWorld的。

 bool AppDelegate::applicationDidFinishLaunching() { 
// initialize director
auto director = Director::getInstance();
auto glview = director->getOpenGLView();
if(!glview) {
glview = GLView::create("My Game");
director->setOpenGLView(glview);
}
// turn on display FPS
director->setDisplayStats(true);
// set FPS. the default value is 1.0/60 if you don't call this
director->setAnimationInterval(1.0 / 60);
// create a scene. it's an autorelease object
auto scene = WelcomeScene::createScene();
// run
director->runWithScene(scene);
returntrue; 
} 
<span style="BACKGROUND-COLOR: #ffffff"></span>

然後,我們可以看到 director->runWithScene。對的,控制場景執行是 導演在執行的。

2.選單按鈕的場景切換

現在來進行場景的切換吧,先要建立一個場景,這裡就用我以前建立的Welcomscene場景,在裡面加一個按鈕,通過按鈕的回撥函式跳轉到程式初始原有的HelloWorld場景中。

這裡,場景的跳轉也有不同方式:

替換,就是用某個場景替換當前場景,原先場景就被釋放掉了。

棧式,將現在的場景儲存,向入棧一樣,壓入棧中,顯示新場景,如果新場景釋放,將原場景顯示。原場景不釋放,耗記憶體大。

①替換

先演示,替換的,主要就是在回撥函式中導演的動作,我先在WelcomeScene場景中新建背景圖層即一個選單按鈕。

WelcomeScene.h:

 #include "cocos2d.h"
classWelcomeScene : publiccocos2d::Layer 
{ 
public:
// 建立場景函式
staticcocos2d::Scene* createScene(); 
virtualbool init(); 
voidmenujumpCallback(cocos2d::Ref* pSender); 
// 是一個巨集定義
CREATE_FUNC(WelcomeScene);
}; 

WelcomeScene.cpp:

#include "WelcomeScene.h"
#include "HelloWorldScene.h"
USING_NS_CC; 
// 建立場景函式 
Scene* WelcomeScene::createScene()
{ 
auto scene = Scene::create();
auto layer = WelcomeScene::create();
scene->addChild(layer);
returnscene; 
} 
boolWelcomeScene::init() 
{ 
// 判斷是否能初始化,若不能則直接返回,退出。
if( !Layer::init() ) 
{
returnfalse; 
}
// 獲得螢幕高度與寬度與起點座標
Size visibleSize = Director::getInstance()->getVisibleSize();
Point origin = Director::getInstance()->getVisibleOrigin();
// 背景圖片
auto mysprite=Sprite::create("backg.png");
mysprite->setPosition(Point(visibleSize.width/2,visibleSize.height/2));
this->addChild(mysprite,0);
// 建立選單按鈕,三個引數,第一個為點選前樣子,第二個為點選後樣子,第三個為點選按鈕所執行的函式(就是回撥函式)
auto jumpItem = MenuItemImage::create(
"icon01.png",
"icon01.png",
CC_CALLBACK_1(WelcomeScene::menujumpCallback,this)); 
// 設定放置按鈕的位置(寬度:螢幕最右側-按鈕的寬度/2,高度:螢幕最下側-按鈕高度/2,因為錨點在中心,所以除以2)
jumpItem->setPosition(Point(origin.x + visibleSize.width - jumpItem->getContentSize().width/2 ,
origin.y + jumpItem->getContentSize().height/2));
// 新增到選單
auto menu = Menu::create(jumpItem, NULL);
menu->setPosition(Point::ZERO);
this->addChild(menu, 1);
returntrue; 
} 
voidWelcomeScene::menujumpCallback(Ref* pSender) 
{ 
// 建立HelloWorld場景
auto scene=HelloWorld::createScene();
// 讓導演 用HelloWorld場景 ☆替換☆ 現在的場景,注意是替換!
Director::getInstance()->replaceScene(scene);
}

注意,要呼叫哪個場景時,不要忘了新增那個場景的標頭檔案。

主要看一下回調函式,建立HelloWorld場景,然後導演執行的replaceScene函式,所以是替換操作。

②棧換

然後再試一試,壓棧出棧的場景跳轉。

這時候,需要兩個場景的配合,以為這樣場景切換,主要用於遊戲進行時,點選暫停,我們需要將現在場景壓棧,然後彈出暫停介面,點選暫停介面返回,這時候就出棧,原場景重現。

這時候,我們改變一下,HelloWorld場景中,關閉按鈕的回撥函式,讓它進行導演的pop操作。

WelcomeScene.cpp,只有回撥函式改變了:

 void WelcomeScene::menujumpCallback(Ref* pSender) 
{ 
// 建立HelloWorld場景
auto scene=HelloWorld::createScene();
// 讓導演 用HelloWorld場景 ☆壓棧☆ 現在的場景
Director::getInstance()->pushScene(scene);
} 
<span style="BACKGROUND-COLOR: #ffffff"></span>

HelloWorldScene.cpp,也是隻有回撥函式改變:

void HelloWorld::menuCloseCallback(Ref* pSender) 
{ 
// 讓導演 ☆出棧☆ 現在的場景
Director::getInstance()->popScene();
}

我們可以Push很多個場景,每一次Pop恢復上一個,當然也可以通過 void popToRootScene() 來回到根場景,就是最初的場景。

這就是第二種進行入棧,出棧式的場景切換。

3.切換動畫效果

Cocos2d-x 引擎,對於切換場景提供了很多動畫效果。

我們來試一試吧。

void WelcomeScene::menujumpCallback(Ref* pSender) 
{ 
auto scene=HelloWorld::createScene();
auto scene02=TransitionZoomFlipY::create(1.0f,scene);
Director::getInstance()->replaceScene(scene02);
}

在第一行建立了HelloWorld場景,在第二行建立動畫效果的場景,第三行導演類執行替換場景,用第二行建立的場景。

一般第二行的引數必要的為兩個(多長時間動畫(浮點型別),切換到的目標場景),第三個可選,一般都有,這次我用的動畫效果API裡是這樣的:

1406511970281054.png

Orientation就是一些轉換方向的型別:

1406511996161890.png

動畫效果還有很多:

//慢慢淡化到另一場景 
TransitionCrossFade::create(時間,目標場景);
//本場景變暗消失後另一場景慢慢出現
TransitionFade::create(時間,目標場景);
//本場景右上角到左下角方塊消失到另一場景
TransitionFadeBL::create(時間,目標場景);
//本場景從上到下橫條消失到另一場景
TransitionFadeDown::create(時間,目標場景);
//本場景左下角到右上角方塊消失到另一場景
TransitionFadeTR::create(時間,目標場景);
//本場景從下到上橫條消失到另一場景
TransitionFadeUp::create(時間,目標場景);
//本場景翻轉消失到另一場景(斜上方)
TransitionFlipAngular::create(時間,目標場景,樣式 );
//本場景翻轉消失到另一場景(X軸)
TransitionFlipX::create(時間,目標場景,樣式);
//本場景翻轉消失到另一場景(Y軸)
TransitionFlipY::create(時間,目標場景);
//本場景跳動消失後另一場景跳動出現
TransitionJumpZoom::create(時間,目標場景);
//另一場景由整體從下面出現
TransitionMoveInB::create(時間,目標場景);
//另一場景由整體從左面出現
TransitionMoveInL::create(時間,目標場景);
//另一場景由整體從上面出現
TransitionMoveInT::create(時間,目標場景);
//另一場景由整體從右面出現
TransitionMoveInR::create(時間,目標場景);
//翻頁切換,bool為true是向前翻。
TransitionPageTurn::create(時間,目標場景,bool);
//本場景從左到右消失同時另一場景出現
TransitionProgressHorizontal::create(時間,目標場景);
//本場景從中間到四周消失同時另一場景出現
TransitionProgressInOut::create(時間,目標場景);
//本場景從四周到中間消失同時另一場景出現
TransitionProgressOutIn::create(時間,目標場景);
//本場景逆時針消失到另一場景
TransitionProgressRadialCCW::create(時間,目標場景);
//本場景順時針消失到另一場景
TransitionProgressRadialCW::create(時間,目標場景);
//本場景從上到下消失同時另一場景出現
TransitionProgressVertical::create(時間,目標場景);
//本場景旋轉消失後另一場景旋轉出現
TransitionRotoZoom::create(時間,目標場景);
//本場景縮小切換到另一場景放大
TransitionShrinkGrow::create(時間,目標場景);
//本場景向上滑動到另一場景
TransitionSlideInB::create(時間,目標場景);
//本場景向右滑動到另一場景
TransitionSlideInL::create(時間,目標場景);
//本場景向左滑動到另一場景
TransitionSlideInR::create(時間,目標場景);
//本場景向下滑動到另一場景
TransitionSlideInT::create(時間,目標場景);
//本場景三矩形上下消失後另一場景三矩形上下出現
TransitionSplitCols::create(時間,目標場景);
//本場景三矩形左右消失後另一場景三矩形左右出現
TransitionSplitRows::create(時間,目標場景);
//本場景小方塊消失到另一場景
TransitionTurnOffTiles::create(時間,目標場景);
//本場景翻轉消失到另一場景(斜上方)
TransitionZoomFlipAngular::create(時間,目標場景,樣式);
//本場景翻轉消失到另一場景(X軸)
TransitionZoomFlipX::create(時間,目標場景,樣式);
//本場景翻轉消失到另一場景(Y軸)
TransitionZoomFlipY::create(時間,目標場景,樣式);