CCDirector類是Cocos2D-x遊戲引擎的核心。它用來建立並且控制着屏幕的顯示,同一時候控制場景的顯示時間和顯示方式。ide
在整個遊戲裏通常僅僅有一個導演。遊戲的開始、結束、暫停都會調用CCDirector類的方法。CCDirector類具備例如如下功能。函數
CCDirector類的繼承關係。如圖3-8所看到的。oop
先看返回單例對象的方法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;}
如下咱們再看一下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是否應該清除。
這段代碼很是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來實現每一幀的邏輯,主要是渲染邏輯。