CCDirector導演類

CCDirector類是Cocos2D-x遊戲引擎的核心。它用來建立並且控制着屏幕的顯示,同一時候控制場景的顯示時間和顯示方式。ide

在整個遊戲裏通常僅僅有一個導演。遊戲的開始、結束、暫停都會調用CCDirector類的方法。CCDirector類具備例如如下功能。函數

  • 初始化OpenGL會話。
  • 設置OpenGL的一些參數和方式。

  • 訪問和改變場景以及訪問Cocos2D-x的配置細節。
  • 訪問視圖。

  • 設置投影和朝向。
需要說明的是,CCDirector是單例模式,調用CCDirector方法的標準方式例如如下:
  • CCDirector::sharedDirector()->函數名

CCDirector類的繼承關係。如圖3-8所看到的。oop


CCDisplayLinkDirector繼承了CCDirector,是一個可以本身主動刷新的導演類。它僅僅支持1/60 、1/30 和1/15三種動畫間隔(幀間隔)。在Cocos2D-x裏面。在遊戲的不論什麼時間,僅僅有一個場景對象實例處於執行狀態。而導演就是流程的總指揮,它負責遊戲全過程的場景切換。這也是典型的面向對象和分層的設計原則。如下分別介紹CCDirector類的成員數據和函數。

先看返回單例對象的方法post

Director* Director::getInstance(){    
if (!s_SharedDirector)    
{       
s_SharedDirector = new DisplayLinkDirector();       
s_SharedDirector->init();    
}    
return s_SharedDirector;}

注意,返回的是DisplayLinkDirector這個類。並且在建立完 DisplayLinkDirector對象以後調用了init方法,看一下init方法。動畫

從這種方法裏面咱們再一次瞭解一下,Director詳細都能幹什麼,和一些內部初始化的工做是怎麼完畢的this

bool Director::init(void){    
setDefaultValues();    
// scenes    
_runningScene = nullptr;    
_nextScene = nullptr;    
_notificationNode = nullptr;    
_scenesStack.reserve(15);    
// FPS    
_accumDt = 0.0f;    
_frameRate = 0.0f;    
_FPSLabel = _drawnBatchesLabel = _drawnVerticesLabel = nullptr;    
_totalFrames = _frames = 0;    
_lastUpdate = new struct timeval;    
// paused ?    
_paused = false;    
// purge ?    
_purgeDirectorInNextLoop = false;    
_winSizeInPoints = Size::ZERO;    
_openGLView = nullptr;    
_contentScaleFactor = 1.0f;  
// scheduler    
_scheduler = new Scheduler();    

// action manager    
_actionManager = new ActionManager();    
_scheduler->scheduleUpdate(_actionManager, Scheduler::PRIORITY_SYSTEM, false);    
_eventDispatcher = new EventDispatcher();    
_eventAfterDraw = new EventCustom(EVENT_AFTER_DRAW);    
_eventAfterDraw->setUserData(this);    
_eventAfterVisit = new EventCustom(EVENT_AFTER_VISIT);    
_eventAfterVisit->setUserData(this);    
_eventAfterUpdate = new EventCustom(EVENT_AFTER_UPDATE);    
_eventAfterUpdate->setUserData(this);    
_eventProjectionChanged = new EventCustom(EVENT_PROJECTION_CHANGED);    
_eventProjectionChanged->setUserData(this);    

//init TextureCache    
initTextureCache();    

_renderer = new Renderer;

#if (CC_TARGET_PLATFORM != CC_PLATFORM_WINRT) && (CC_TARGET_PLATFORM != CC_PLATFORM_WP8)    
_console = new Console;
#endif    
return true;}

可以看到。Director這個大管家初始化了 ActionManager 動做管理器,並將 _actionManager加到了定時器裏。初始化了EventDispatcher EventCustom 等事件。初始化了紋理 和渲染器 Rendere。

如下咱們再看一下DisplayLinkDirector這個類。這是Director的實體類。
spa

class DisplayLinkDirector : public Director
{
public:    
 DisplayLinkDirector(): _invalid(false){}   
 
//    
// Overrides    
//    
virtual void mainLoop() override;    
virtual void setAnimationInterval(double value) override;    
virtual void startAnimation() override;    
virtual void stopAnimation() override;

protected:    
 bool _invalid;};
這個類實現了Director的幾個關鍵的虛函數。mainLoop這個是最基本的了,上面咱們一再說邏輯循環,事實上都是指這個函數。所有的操做,動畫,渲染。定時器都在這裏驅動的。遊戲主循環裏重複的調度 mainLoop來一幀一幀的實現遊戲的各類動做。動畫……. mainLoop來決定當前幀該運行什麼。是否到時間運行等等。

void DisplayLinkDirector::mainLoop()
{    
if (_purgeDirectorInNextLoop){
     _purgeDirectorInNextLoop = false;
     purgeDirector();    
   }else if (!_invalid)    
       {drawScene();             
       // release the objects        
       PoolManager::getInstance()->getCurrentPool()->clear();    
       }
}
代碼很是easy,依據對 purgeDirectorInNextLoop 推斷來決定mainLoop是否應該清除。
_invalid來決定 Director是否應該進行邏輯循環。

這段代碼很是easy,主要操做都封閉到了 drawScene裏面後面咱們跟進drawScene來看看每個邏輯幀都幹了些什麼。

後面另外一句代碼:PoolManager::getInstance()->getCurrentPool()->clear(); 設計

從命名上來看是作清除操做,應該是內存操做,每幀回收不用的引用對象應該是在這裏觸發的,咱們在內存應用的章節再回過頭來討論這塊。
如下看drawScene的代碼
code

void Director::drawScene(){    

// 計算幀之間的時間間隔,如下依據這個時間間隔來推斷是否應該進行某某操做    
calculateDeltaTime();        

// skip one flame when _deltaTime equal to zero.    
if(_deltaTime < FLT_EPSILON) {return;}    
if(_openGLView){_openGLView->pollInputEvents();}    

//Director沒有暫停的狀況下,更新定時器。分發 update後的消息    
if(!_paused){ 
_scheduler->update(_deltaTime);
_eventDispatcher->dispatchEvent(_eventAfterUpdate);}  
  
// opengl清理
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    

/*設置下個場景*/    
if (_nextScene){
setNextScene();}    

kmGLPushMatrix();    

// global identity matrix is needed... come on kazmath!    
kmMat4 identity;    
kmMat4Identity(&identity);  
  
// 渲染場景    
if (_runningScene)    
{_runningScene->visit(_renderer, identity, false);

// 分發場景渲染後的消息         
_eventDispatcher->dispatchEvent(_eventAfterVisit);}    

// 渲染notifications 結點,這個結點有什麼用現在還看不太清楚,後面章節咱們必定會摸清楚的    

if (_notificationNode){_notificationNode->visit(_renderer, identity, false);    }    
if (_displayStats){showStats();}    // 渲染 FPS等幀頻顯示
_renderer->render();     // 調用了渲染器的render方法。詳細咱們在分析Render類的時候再回過來看都幹了些什麼   
 
_eventDispatcher->dispatchEvent(_eventAfterDraw); 
   
kmGLPopMatrix();    
_totalFrames++;    

// swap buffers    
if (_openGLView){_openGLView->swapBuffers();}    
if (_displayStats){calculateMPF();}

}

到現在,咱們完整的分析了Director類,瞭解了這個大管家都管理了哪些對象。對象

如下咱們作個總結。Director主要管理了場景,四個事件的分發,渲染, Opengl對象等。它主要是以場景爲單位來控制遊戲的邏輯幀,經過場景的切換來實現遊戲中不一樣界面的變化。mainloop這個函數調用了drawscene來實現每一幀的邏輯,主要是渲染邏輯。

相關文章
相關標籤/搜索