Director类源代码不完全分析

一, 帧与帧之间时间间隔
/* 标记是否下次帧逻辑时是否清除(忽略)_deltaTime */
    bool _nextDeltaTimeZero;    
/* 上一次逻辑帧运行到当前的时间间隔,用来判断是否应该进行下次逻辑帧,上一次帧执行的时间记录在 _lastUpdate 变量里面*/
    float _deltaTime;

下面两个函数是用来操作下一次的 _deltaTime是否有效的,当整个游戏暂停的时候,这时_deltaTime会不断累计,就会用到了_nextDeltaTimeZero这个变量,标记着下次的_deltaTime为0这样就会不出现恢复暂停后跳帧,而是继续当前帧顺序开始。

inline bool isNextDeltaTimeZero() { return _nextDeltaTimeZero; }
    void setNextDeltaTimeZero(bool nextDeltaTimeZero);

计算_deltaTime的函数,会在每个逻辑循环里面都调用。
/** 计算 deltaTime 上次逻辑帧调用的时间和当前时间的时间间隔。如果 nextDeltaTimeZero为true则deltaTime为0*/    
    void calculateDeltaTime();    
/* 上次主循环帧执行到当前的时间间隔 _deltaTime */
    float getDeltaTime()  const;

二, Scene管理
/* 当前正在执行的场景,由这个变量可以知道,Cocos2d-x同一时间只能执行一个场景。*/
    Scene *_runningScene;
    
    /* 下一个要执行的场景,这块肯定是在场景切换的时候要用到的 */
    Scene *_nextScene;
    
    /* 是否清除场景的标记,当为真时,旧的场景就收到清除消息 */
    bool _sendCleanupToScene;

    /* 场景的堆栈 */
    Vector _scenesStack;

Cocos2d-x同时只能执行一个场景,场景切换的时候有一个 _nextScene。清除场景时有一个标记 _scendCleanupToScene,等待执行的场景都存在 一个栈里面 _scenesStack

    /** 通过调用 `popToSceneStackLevel(1)` 这个方法来实现清理栈里的场景只留下根场景,就是剩下第一个入栈的场景     */
    void popToRootScene();

    /** 按栈的层次来清理栈里的场景,level=0全清除 =1时 为 popToRootScene() 如果值超出了栈里的场景数量则不处理     */
     void popToSceneStackLevel(int level);

/* * 清除Direct的内存缓存,看下源码可以大概了解都有字体,纹理,文件等内存资源      */
    void  purgeCachedData();

   
/* * 设置默认值,具体有哪些看下代码就知道了,很清楚写的 */
    void setDefaultValues();


三,整个游戏的循环
int Application ::run()
{
    initGLContextAttrs();
    if(!applicationDidFinishLaunching())  //没初始化成功
    {
       
return 1 ;
    }
    
    // Retain glview to avoid glview being released in the while loop
    glview->
retain ();
   
   
while (!glview-> windowShouldClose ())
    {
        lastTime = getCurrentMillSecond();     //当前帧开始的时间
       
        director->mainLoop();                  //一个游戏循环内的所有事件和内容
        glview-> pollEvents ();                   

        curTime = getCurrentMillSecond();      //执行完一个循环后的时间
        if (curTime - lastTime < _animationInterval )   //相减得到绘制一帧所需要的时间,如果小于设置的帧率时间,
        {                                              //则休眠,直至下一次循环更新的时间
            usleep ( static_cast < useconds_t >(( _animationInterval - curTime + lastTime)* 1000 ));
        }
    }
ps: 帧率是指程序中画面的绘制速度,通常称为每秒帧数,cocos2dx中默认为60fps
virtual void setAnimationInterval( double interval) //设置方法,参数为帧率倒数,1.0/60

tips: application里面有一个run方法 ,在run方法里面有一个死循环,那个是游戏的主循环,在那个死循环里不断的调用 director->mainLoop这个就是在主游戏循环里不断的执行逻辑帧的操作.

四,内存
/** Removes all cocos2d cached data.
    void purgeCachedData(); //清除内存缓存
/** Sets the default values based on the Configuration info. */
    void setDefaultValues();//设置默认值(字体,纹理等等)

五,OpenGL操作
/** Sets the OpenGL default values.
    void setGLDefaultValues();//设置OpenGL默认值

/** Enables/disables OpenGL alpha blending. 
    void setAlphaBlending( bool on);//设置是否开启透明

/** Sets clear values for the color buffers,
    void setClearColor( const Color4F & clearColor);

/** Enables/disables OpenGL depth test. */
    void setDepthTest(bool on);//是否开启深度测试

六,单例及初始化子类
Director * Director ::getInstance()
{
    if (! s_SharedDirector )
    {
       
s_SharedDirector = new ( std :: nothrow ) DisplayLinkDirector ();
        s_SharedDirector -> init ();//初始化了事件,定时器,渲染器等等等等
    }
    return s_SharedDirector ;
}
DisplayLinkDirector类为Director的子类
在这个类中实现了几个Director中关键的虚函数
   virtual void mainLoop() override
    virtual void setAnimationInterval( double value) override ;
    virtual void startAnimation() override ;
   virtual void stopAnimation() override;

void DisplayLinkDirector ::mainLoop()
{
   
if ( _purgeDirectorInNextLoop )
    {
       
_purgeDirectorInNextLoop = false ; //判断是否应该清除Director
       
purgeDirector ();
    }
   
else if ( _restartDirectorInNextLoop )
    {
       
_restartDirectorInNextLoop = false ;
       
restartDirector ();
    }
   
else if (! _invalid )//判断是否进行逻辑循环
    {
        drawScene(); //渲染
        // release the objects
        PoolManager :: getInstance ()-> getCurrentPool ()-> clear ();//release内存池元素
    }
}

void Director ::drawScene()
{
    // calculate "global" dt
    calculateDeltaTime();//计算帧之间的时间间隔,根据这个时间间隔判断进行什么操作
   
   
if ( _openGLView )
    {
       
_openGLView -> pollEvents ();
    }

    if (! _paused )//没有暂停情况下,更新计时器,分发更新后的消息
    {
       
_scheduler -> update ( _deltaTime );
       
_eventDispatcher -> dispatchEvent ( _eventAfterUpdate );
    }
    //OpenGL清理
   
_renderer -> clear (); 
   
experimental :: FrameBuffer :: clearAllFBOs ();
   
    if ( _nextScene )//设置下一个场景
    {
       
setNextScene ();
    }

   
pushMatrix ( MATRIX_STACK_TYPE :: MATRIX_STACK_MODELVIEW );
   
   
if ( _runningScene )
    {
#if (CC_USE_PHYSICS || (CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION) || CC_USE_NAVMESH)
        _runningScene -> stepPhysicsAndNavigation ( _deltaTime );
#endif
        //clear draw stats
       
_renderer -> clearDrawStats ();
       
       
//render the scene渲染场景
       
_runningScene -> render ( _renderer );
        //分发渲染后的消息
       
_eventDispatcher -> dispatchEvent ( _eventAfterVisit );
    }

   
// draw the notifications node
   
if ( _notificationNode )
    {
       
_notificationNode -> visit ( _renderer , Mat4 :: IDENTITY , 0 );
    }

   
if ( _displayStats )
    {
       
showStats ();
    }
   
_renderer -> render ();

   
_eventDispatcher -> dispatchEvent ( _eventAfterDraw );

   
popMatrix ( MATRIX_STACK_TYPE :: MATRIX_STACK_MODELVIEW );

   
_totalFrames ++;

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

   
if ( _displayStats )
    {
       
calculateMPF ();
    }
}

七,
/** Director will trigger an event when projection type is changed. */
   
static const char *EVENT_PROJECTION_CHANGED;
   
/** Director will trigger an event after Schedule::update() is invoked. */
   
static const char * EVENT_AFTER_UPDATE;
   
/** Director will trigger an event after Scene::render() is invoked. */
   
static const char * EVENT_AFTER_VISIT;
   
/** Director will trigger an event after a scene is drawn, the data is sent to GPU. */
    static const char* EVENT_AFTER_DRAW;
事件类型:changed,update,visit,draw
待补充

你可能感兴趣的:(Director类源代码不完全分析)