cocos2dx 3.17.1 导演类

  进入导演类的头文件,首先看到的是一些头文件的引用:CCPlatformMacros(适配),CCRef(继承的父类),CCVector(3.0以后的新向量),CCScene(场景),CCMath(数学方法),CCGL(OpenGL);接下来是一堆类的声明:LabelAtlas(标签),DirectorDelegate(不知道),Node(节点),Scheduler(调度器),ActionManager(动作管理器),EventDispatcher(时间分发),EventCustom(自定义事件),EventListenerCustom(自定义事件监听),TextureCache(纹理缓存),Renderer(渲染队列),Camera(相机),Console(控制台),FrameBuffer(帧缓存);把OpenGL的类屏蔽掉了,可能是在别的渲染管理类中,后面分析渲染机制再看

#ifndef __CCDIRECTOR_H__
#define __CCDIRECTOR_H__

#include <stack>
#include <thread>
#include <chrono>

#include "platform/CCPlatformMacros.h"
#include "base/CCRef.h"
#include "base/CCVector.h"
#include "2d/CCScene.h"
#include "math/CCMath.h"
#include "platform/CCGL.h"
#include "platform/CCGLView.h"

NS_CC_BEGIN

/**
 * @addtogroup base
 * @{
 */

/* 提前声明. */
class LabelAtlas;
//class GLView;
class DirectorDelegate;
class Node;
class Scheduler;
class ActionManager;
class EventDispatcher;
class EventCustom;
class EventListenerCustom;
class TextureCache;
class Renderer;
class Camera;

class Console;
namespace experimental
{
    class FrameBuffer;
}

   之后看到导演类的定义,是继承于Ref父类的,进入父类查看它的作用,进入父类发现它的代码量并不多,有几个关键的函数retain(),release(),autorelease(),他们的作用在这个类中也很明显,就是cocos2dx的内存管理机制--计数机制;当对象被生成出来,就会被加入到对象池,计数为1,如果没有被加入对象,下一帧计数-1,当计数为0 就自动被对象池清理,retain()函数就是手动增加一次计数,相对应的release()就是手动释放一次。

    /** Director will trigger an event before set next scene. */
    static const char* EVENT_BEFORE_SET_NEXT_SCENE;
    /** Director will trigger an event after set next scene. */
    static const char* EVENT_AFTER_SET_NEXT_SCENE;
    
    /** Director will trigger an event when projection type is changed. */
    static const char* EVENT_PROJECTION_CHANGED;
    /** Director will trigger an event before Schedule::update() is invoked. */
    static const char* EVENT_BEFORE_UPDATE;
    /** Director will trigger an event after Schedule::update() is invoked. */
    static const char* EVENT_AFTER_UPDATE;
    /** Director will trigger an event while resetting Director */
    static const char* EVENT_RESET;
    /** 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;
    /** Director will trigger an event before a scene is drawn, right after clear. */
    static const char* EVENT_BEFORE_DRAW;

  这些代码定义了导演类的事件,看名字定义,应该是导演在事件发生的时候的处理,具体再看。

    enum class Projection
    {
        /// Sets a 2D projection (orthogonal projection).
        _2D,
        
        /// Sets a 3D projection with a fovy=60, znear=0.5f and zfar=1500.
        _3D,
        
        /// It calls "updateProjection" on the projection delegate.
        CUSTOM,
        
        /// Default projection is 3D projection.
        DEFAULT = _3D,
    };
    

  对于模型的的一个枚举变量,看这里的Projection定义,我猜测应该是这个模型发生改变的时候,导演上面定义的事件进行对应的改变。

    static Director* getInstance();

    /**
     * @deprecated Use getInstance() instead.
     * @js NA
     */
    CC_DEPRECATED_ATTRIBUTE static Director* sharedDirector() { return Director::getInstance(); }
    
    /**
     * @js ctor
     */
    Director();
    
    /**
     * @js NA
     * @lua NA
     */
    ~Director();  

  导演类是一个单实例,sharedDirector现在被getInstance方法代替

bool init();

    // attribute

    /** Gets current running Scene. Director can only run one Scene at a time. */
    Scene* getRunningScene() { return _runningScene; }

    /** Gets the FPS value. */
    float getAnimationInterval() { return _animationInterval; }
    /** Sets the FPS value. FPS = 1/interval. */
    void setAnimationInterval(float interval);

    /** Whether or not displaying the FPS on the bottom-left corner of the screen. */
    bool isDisplayStats() { return _displayStats; }
    /** Display the FPS on the bottom-left corner of the screen. */
    void setDisplayStats(bool displayStats) { _displayStats = displayStats; }
    
    /** Get seconds per frame. */
    float getSecondsPerFrame() { return _secondsPerFrame; }

    /** 
     * Get the GLView.
     * @lua NA
     */
    GLView* getOpenGLView() { return _openGLView; }
    /** 
     * Sets the GLView. 
     * @lua NA
     */
    void setOpenGLView(GLView *openGLView);

    /*
     * Gets singleton of TextureCache.
     * @js NA
     */
    TextureCache* getTextureCache() const;

    /** Whether or not `_nextDeltaTimeZero` is set to 0. */
    bool isNextDeltaTimeZero() { return _nextDeltaTimeZero; }
    /** 
     * Sets the delta time between current frame and next frame is 0.
     * This value will be used in Schedule, and will affect all functions that are using frame delta time, such as Actions.
     * This value will take effect only one time.
     */
    void setNextDeltaTimeZero(bool nextDeltaTimeZero);

    /** Whether or not the Director is paused. */
    bool isPaused() { return _paused; }

    /** How many frames were called since the director started */
    unsigned int getTotalFrames() { return _totalFrames; }
    
    /** Gets an OpenGL projection.
     * @since v0.8.2
     * @lua NA
     */
    Projection getProjection() { return _projection; }
    /** Sets OpenGL projection. */
    void setProjection(Projection projection);
    
    /** Sets the glViewport.*/
    void setViewport();
    
    /** Whether or not the replaced scene will receive the cleanup message.
     * If the new scene is pushed, then the old scene won't receive the "cleanup" message.
     * If the new scene replaces the old one, the it will receive the "cleanup" message.
     * @since v0.99.0
     */
    bool isSendCleanupToScene() { return _sendCleanupToScene; }

    /** This object will be visited after the main scene is visited.
     * This object MUST implement the "visit" function.
     * Useful to hook a notification object, like Notifications (http://github.com/manucorporat/CCNotifications)
     * @since v0.99.5
     */
    Node* getNotificationNode() const { return _notificationNode; }
    /** 
     * Sets the notification node.
     * @see Director::getNotificationNode()
     */
    void setNotificationNode(Node *node);
    
    // window size

    /** Returns the size of the OpenGL view in points. */
    const Size& getWinSize() const;

    /** Returns the size of the OpenGL view in pixels. */
    Size getWinSizeInPixels() const;
    
    /** 
     * Returns visible size of the OpenGL view in points.
     * The value is equal to `Director::getWinSize()` if don't invoke `GLView::setDesignResolutionSize()`.
     */
    Size getVisibleSize() const;
    
    /** Returns visible origin coordinate of the OpenGL view in points. */
    Vec2 getVisibleOrigin() const;

    /**
     * Returns safe area rectangle of the OpenGL view in points.
     */
    Rect getSafeAreaRect() const;

    /**
     * Converts a screen coordinate to an OpenGL coordinate.
     * Useful to convert (multi) touch coordinates to the current layout (portrait or landscape).
     */
    Vec2 convertToGL(const Vec2& point);

    /** 
     * Converts an OpenGL coordinate to a screen coordinate.
     * Useful to convert node points to window points for calls such as glScissor.
     */
    Vec2 convertToUI(const Vec2& point);

    /** 
     * Gets the distance between camera and near clipping frame.
     * It is correct for default camera that near clipping frame is same as the screen.
     */
    float getZEye() const;

  这里定义了很多获取方法,首先一个init()方法,在cpp文件里面去看,init整个director对象的初始化工作都在这里面,初始化了 ActionManager 动作管理器 并将 _actionManager加到了定时器里,初始化了EventDispatcher EventCustom 等事件,初始化了纹理 和渲染器 Renderer

bool Director::init(void)
{
    setDefaultValues();

    _scenesStack.reserve(15);

    // FPS
    _lastUpdate = std::chrono::steady_clock::now();
    
    _console = new (std::nothrow) Console;

    // scheduler
    _scheduler = new (std::nothrow) Scheduler();
    // action manager
    _actionManager = new (std::nothrow) ActionManager();
    _scheduler->scheduleUpdate(_actionManager, Scheduler::PRIORITY_SYSTEM, false);

    _eventDispatcher = new (std::nothrow) EventDispatcher();
    
    _beforeSetNextScene = new (std::nothrow) EventCustom(EVENT_BEFORE_SET_NEXT_SCENE);
    _beforeSetNextScene->setUserData(this);
    _afterSetNextScene = new (std::nothrow) EventCustom(EVENT_AFTER_SET_NEXT_SCENE);
    _afterSetNextScene->setUserData(this);
    _eventAfterDraw = new (std::nothrow) EventCustom(EVENT_AFTER_DRAW);
    _eventAfterDraw->setUserData(this);
    _eventBeforeDraw = new (std::nothrow) EventCustom(EVENT_BEFORE_DRAW);
    _eventBeforeDraw->setUserData(this);
    _eventAfterVisit = new (std::nothrow) EventCustom(EVENT_AFTER_VISIT);
    _eventAfterVisit->setUserData(this);
    _eventBeforeUpdate = new (std::nothrow) EventCustom(EVENT_BEFORE_UPDATE);
    _eventBeforeUpdate->setUserData(this);
    _eventAfterUpdate = new (std::nothrow) EventCustom(EVENT_AFTER_UPDATE);
    _eventAfterUpdate->setUserData(this);
    _eventProjectionChanged = new (std::nothrow) EventCustom(EVENT_PROJECTION_CHANGED);
    _eventProjectionChanged->setUserData(this);
    _eventResetDirector = new (std::nothrow) EventCustom(EVENT_RESET);
    //init TextureCache
    initTextureCache();
    initMatrixStack();

    _renderer = new (std::nothrow) Renderer;
    RenderState::initialize();

#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
    EngineDataManager::init();
#endif
    return true;
}
init做的事情

接下来继续看,都是一些设置,获取,判断是否存在,转换坐标的方法,直到runScene():

 void runWithScene(Scene *scene);

    /** 
    *暂停正在运行的场景的执行,将其推送到暂停场景的堆栈上。
    *将执行新场景。
    *尽量避免大量推送场景以减少内存分配。
    *只有在有运行场景时才调用它。
     */
    void pushScene(Scene *scene);

    /** 
    *从堆栈中弹出一个场景。
    *此场景将取代正在运行的场景。
    *将删除正在运行的场景。 如果堆栈中没有更多场景,则终止执行。
    *只有在有运行场景时才调用它
     */
    void popScene();

    /** 
    *弹出堆栈中的所有场景,直到队列中的根场景。
    *此场景将取代正在运行的场景。
    *在内部,它将调用`popToSceneStackLevel(1)`。
     */
    void popToRootScene();

    /** 弹出堆栈中的所有场景,直到达到“level”。
      如果level为0,它将结束导演。
      如果level为1,它将弹出所有场景,直到它到达根场景。
      如果level <=比当前堆栈级别,它将不会执行任何操作。
     */
     void popToSceneStackLevel(int level);

    /** 用新的替换正在运行的场景。 正在运行的场景已终止。
      *只有在有运行场景时才调用它。
     * @js NA
     */
    void replaceScene(Scene *scene);

    /** 结束执行,释放运行场景。
     * @lua endToLua
     */
    void end();

    /*
    * 暂停正在运行的场景。
    *正在运行的场景将被_drawed_但所有预定的计时器将被暂停。
    *暂停时,绘制速率为4 FPS以减少CPU消耗。
     */
    void pause();

    /** 恢复暂停的场景。
      *计划的计时器将再次激活。
      *“增量时间”将为0(就好像游戏没有暂停一样)。
     */
    void resume();
    
    /*
     * Restart the director.重启导演。 
     * @js NA
     */
    void restart();
    /** Stops the animation. Nothing will be drawn. The main loop won't be triggered anymore.
     * If you don't want to pause your animation call [pause] instead.
     *停止动画。 什么都不会被画出来。 主循环不再被触发。
     *如果您不想暂停动画调用[暂停]。
     */
    void stopAnimation();

    /** The main loop is triggered again.
     * Call this function only if [stopAnimation] was called earlier.
     * @warning Don't call this function to start the main loop. To run the main loop call runWithScene.
     *主循环再次被触发。
     *仅在先前调用[stopAnimation]时调用此函数。
     * @warning不要调用此函数来启动主循环。 要运行主循环,请调用runWithScene。
     */
    void startAnimation();

    /** Draw the scene.
     * This method is called every frame. Don't call it manually.
     *画出场景。
     *每帧调用此方法。 不要手动调用它。
     */
    void drawScene();

 

之后的方法都是设置,获取各个属性,在注释中看的很清楚

 /** Removes all cocos2d cached data.
     * It will purge the TextureCache, SpriteFrameCache, LabelBMFont cache
     * @since v0.99.3
     *删除所有cocos2d缓存数据。
     *它将清除TextureCache,SpriteFrameCache,LabelBMFont缓存
     * @since v0.99.3
     */
    void purgeCachedData();

    /** Sets the default values based on the Configuration info.根据配置信息设置默认值 */
    void setDefaultValues();

    // OpenGL Helper

    /** Sets the OpenGL default values.
     * It will enable alpha blending, disable depth test.
     *设置OpenGL默认值。
     *它将启用alpha混合,禁用深度测试。
     * @js NA
     */
    void setGLDefaultValues();

    /** Enables/disables OpenGL alpha blending. */
    void setAlphaBlending(bool on);
    
    /** Sets clear values for the color buffers,
     * value range of each element is [0.0, 1.0].
     *设置颜色缓冲区的清除值,
     *每个元素的值范围是[0.0,1.0]。
     * @js NA
     */
    void setClearColor(const Color4F& clearColor);

    /** Enables/disables OpenGL depth test. */
    void setDepthTest(bool on);

    void mainLoop();
    /** Invoke main loop with delta time. Then `calculateDeltaTime` can just use the delta time directly.
     * The delta time paseed may include vsync time. See issue #17806
     *使用增量时间调用主循环。 然后`calculateDeltaTime`可以直接使用delta时间。
     *增量时间可能包括vsync时间。 请参阅问题#17806
     * @since 3.16
     */
    void mainLoop(float dt);

    /** The size in pixels of the surface. It could be different than the screen size.
     * High-res devices might have a higher surface size than the screen size.
     * Only available when compiled using SDK >= 4.0.
     * @since v0.99.4

     *他的表面像素大小。 它可能与屏幕尺寸不同。
     *高分辨率设备的表面尺寸可能大于屏幕尺寸。
     *仅在使用SDK> = 4.0编译时可用。
     */
    void setContentScaleFactor(float scaleFactor);
    /**
     * Gets content scale factor.
     * @see Director::setContentScaleFactor()
     *获取内容比例因子。
     * @see Director :: setContentScaleFactor()
     */
    float getContentScaleFactor() const { return _contentScaleFactor; }

    /** Gets the Scheduler associated with this director.
     * @since v2.0
     */
    Scheduler* getScheduler() const { return _scheduler; }
    
    /** Sets the Scheduler associated with this director.
     *设置与此director关联的Scheduler
     * @since v2.0
     */
    void setScheduler(Scheduler* scheduler);

    /** Gets the ActionManager associated with this director.
    *获取与此director关联的ActionManager。
     * @since v2.0
     */
    ActionManager* getActionManager() const { return _actionManager; }
    
    /** Sets the ActionManager associated with this director.
     *设置与此导演关联的ActionManager。
     * @since v2.0
     */
    void setActionManager(ActionManager* actionManager);
    
    /** Gets the EventDispatcher associated with this director.
    *获取与此director关联的EventDispatcher。
     * @since v3.0
     * @js NA
     */
    EventDispatcher* getEventDispatcher() const { return _eventDispatcher; }
    
    /** Sets the EventDispatcher associated with this director.设置与此director关联的EventDispatcher。
     * @since v3.0
     * @js NA
     */
    void setEventDispatcher(EventDispatcher* dispatcher);

    /** Returns the Renderer associated with this director.返回与此director关联的Renderer。
     * @since v3.0
     */
    Renderer* getRenderer() const { return _renderer; }

    /** Returns the Console associated with this director.
     * @since v3.0
     * @js NA
     */
    Console* getConsole() const { return _console; }

    /* Gets delta time since last tick to main loop. */
    float getDeltaTime() const;
    
    /**
     *  Gets Frame Rate.
     * @js NA
     */
    float getFrameRate() const { return _frameRate; }

    /** 
     * Clones a specified type matrix and put it to the top of specified type of matrix stack.
     * @js NA
     */
    void pushMatrix(MATRIX_STACK_TYPE type);

    /**
     * Clones a projection matrix and put it to the top of projection matrix stack.
     * @param index The index of projection matrix stack.
     * @js NA
     */
    void pushProjectionMatrix(size_t index);

    /** Pops the top matrix of the specified type of matrix stack.
     * @js NA
     */
    void popMatrix(MATRIX_STACK_TYPE type);

    /** Pops the top matrix of the projection matrix stack.
     * @param index The index of projection matrix stack.
     * @js NA
     */
    void popProjectionMatrix(size_t index);

    /** Adds an identity matrix to the top of specified type of matrix stack.
     * @js NA
     */
    void loadIdentityMatrix(MATRIX_STACK_TYPE type);

    /** Adds an identity matrix to the top of projection matrix stack.
     * @param index The index of projection matrix stack.
     * @js NA
     */
    void loadProjectionIdentityMatrix(size_t index);

    /**
     * Adds a matrix to the top of specified type of matrix stack.
     * 
     * @param type Matrix type.
     * @param mat The matrix that to be added.
     * @js NA
     */
    void loadMatrix(MATRIX_STACK_TYPE type, const Mat4& mat);

    /**
     * Adds a matrix to the top of projection matrix stack.
     *
     * @param mat The matrix that to be added.
     * @param index The index of projection matrix stack.
     * @js NA
     */
    void loadProjectionMatrix(const Mat4& mat, size_t index);

    /**
     * Multiplies a matrix to the top of specified type of matrix stack.
     *
     * @param type Matrix type.
     * @param mat The matrix that to be multiplied.
     * @js NA
     */
    void multiplyMatrix(MATRIX_STACK_TYPE type, const Mat4& mat);

    /**
     * Multiplies a matrix to the top of projection matrix stack.
     *
     * @param mat The matrix that to be multiplied.
     * @param index The index of projection matrix stack.
     * @js NA
     */
    void multiplyProjectionMatrix(const Mat4& mat, size_t index);

    /**
     * Gets the top matrix of specified type of matrix stack.
     * @js NA
     */
    const Mat4& getMatrix(MATRIX_STACK_TYPE type) const;

    /**
     * Gets the top matrix of projection matrix stack.
     * @param index The index of projection matrix stack.
     * @js NA
     */
    const Mat4& getProjectionMatrix(size_t index) const;

    /**
     * Clear all types of matrix stack, and add identity matrix to these matrix stacks.
     * @js NA
     */
    void resetMatrixStack();

    /**
     * Init the projection matrix stack.
     * @param stackCount The size of projection matrix stack.
     * @js NA
     */
    void initProjectionMatrixStack(size_t stackCount);

    /**
     * Get the size of projection matrix stack.
     * @js NA
     */
    size_t getProjectionMatrixStackSize();

    /**
     * returns the cocos2d thread id.
     Useful to know if certain code is already running on the cocos2d thread
     */
    const std::thread::id& getCocos2dThreadId() const { return _cocos2d_thread_id; }

    /**
     * returns whether or not the Director is in a valid state
     */
    bool isValid() const { return !_invalid; }

   Director主要管理了场景,以场景为单位来控制游戏的逻辑帧,通过场景的切换来实现游戏中不同界面的变化。mainloop这个函数 调用 了drawscene来实现每一帧的逻辑主要是渲染逻辑。application里面有一个run方法 ,在run方法里面有一个死循环,那个是游戏的主循环,在那个死循环里不断的调用 director->mainLoop这个就是在主游戏循环里不断的执行逻辑帧的操作.

posted @ 2019-03-17 17:32  博_客园的张斯瑞  阅读(629)  评论(0编辑  收藏  举报