cocos2d-x CCNode,CCLayer,CCScene分析-沈大海cocos2d-x教程12

时间:2023-02-07 18:16:12

说说这一家子,

CCNode是父亲,CCLayer和CCScene是他2个孩子,CCScene 负责和CCDirector打交道,负责管理CCNode 所有的孩子(这个CCNode不知道有多少孩子,孙子)

CCNode

   |                   |

CCLayer   CCScene

--------------------------------------------------------------------------------------------------------------

CCNode核心属性和方法

class CC_DLL CCNode : public CCObject
{

     CC_PROPERTY_READONLY(int, m_nZOrder, ZOrder)   

     CC_PROPERTY(float, m_fVertexZ, VertexZ)                  //设定Node的绘制排序 数值越小越先绘制

     CC_PROPERTY(float, m_fRotation, Rotation)            //旋转角度

     float getScale();                                                                 //缩放比例,0。5是一半
     void setScale(float scale);

    CC_PROPERTY(float, m_fScaleX, ScaleX)       

    CC_PROPERTY(float, m_fScaleY, ScaleY)

    CC_PROPERTY_PASS_BY_REF(CCPoint, m_tPosition, Position)

    const CCPoint& getPositionLua(void);
    void getPosition(float* x, float* y);
    float getPositionX(void);
    float getPositionY(void);
    void setPositionX(float x);                                  //设定坐标 (Opengl 坐标系)
    void setPositionY(float y);
    void setPosition(float x, float y);
    void _setZOrder(int z);
    CC_PROPERTY(float, m_fSkewX, SkewX)//设定扭曲角度

    CC_PROPERTY(float, m_fSkewY, SkewY)

    CC_PROPERTY_READONLY(CCArray*, m_pChildren, Children) //获取所有子节点

    unsigned int getChildrenCount(void);

    CC_PROPERTY_READONLY(CCCamera *, m_pCamera, Camera)//获取摄像机对象,通过他可以修改视口

    CC_PROPERTY(CCGridBase *, m_pGrid, Grid)

  protected:
    bool m_bIsVisible;                                                       //是否绘制
public:
    virtual bool isVisible();
    virtual void setVisible(bool visible);

    CC_PROPERTY_PASS_BY_REF(CCPoint, m_tAnchorPoint, AnchorPoint)   //锚点是在进行旋转和缩放等动作时候的中心点

    CC_PROPERTY_READONLY_PASS_BY_REF(CCPoint, m_tAnchorPointInPoints, AnchorPointInPoints)

    CC_PROPERTY_PASS_BY_REF(CCSize, m_tContentSize, ContentSize)  //节点的尺寸,不会因为变换而改变

    bool m_bIsRunning;                                          //是否正在运行
    bool isRunning();

    CC_PROPERTY(CCNode *, m_pParent, Parent) //父节点

    bool m_bIgnoreAnchorPointForPosition;
    bool isIgnoreAnchorPointForPosition();
    void ignoreAnchorPointForPosition(bool isIgnoreAnchorPointForPosition);

    CC_PROPERTY(int, m_nTag, Tag)         //node编号,可以使用该tag来获取该node对象

    CC_PROPERTY(void *, m_pUserData, UserData)                             //用来连接Box2d
    CC_SYNTHESIZE_RETAIN(CCObject*, m_pUserObject, UserObject);

    CC_SYNTHESIZE_RETAIN(CCGLProgram*, m_pShaderProgram, ShaderProgram);//Shader管理器

    CC_SYNTHESIZE(int, m_nOrderOfArrival, OrderOfArrival);

    CC_SYNTHESIZE(ccGLServerState, m_glServerState, GLServerState);     //opengl管理器

    CC_PROPERTY(CCActionManager*, m_pActionManager, ActionManager);    //动作管理器

    CC_PROPERTY(CCScheduler*, m_pScheduler, Scheduler); //任务管理器

    inline int getScriptHandler() { return m_nScriptHandler; };

protected:

    CCAffineTransform m_tTransform, m_tInverse;    //坐标变换对象

    bool m_bIsTransformDirty;
    bool m_bIsInverseDirty;
    bool m_bReorderChildDirty;
    int m_nScriptHandler;
    ccScriptType m_eScriptType;
private:
    void childrenAlloc(void);

    void insertChild(CCNode* child, int z);

    void setZOrder(int z);
    
    void detachChild(CCNode *child, bool doCleanup);

    CCPoint convertToWindowSpace(const CCPoint& nodePoint);//转化为窗口坐标

public:

    CCNode(void);

    virtual ~CCNode(void);

    const char* description(void);

    CC_DEPRECATED_ATTRIBUTE static CCNode * node(void);

    static CCNode * create(void);         //节点创建方法

    virtual void onEnter();                       //开始绘制node

    virtual void onEnterTransitionDidFinish();//动画场景播放完成开始绘制node

    virtual void onExit();                         //退出node

    virtual void onExitTransitionDidStart();//

//--------------------------------------------------------------------------------------------------------------------------------------------

  1. ?~~ HelloWorld::onEnter
    ?~~ HelloWorld::onEnterTransitionDidFinish
    ?~~HelloWorld2::onEnter
    ?~~HelloWorld::onExit
    ?~~HelloWorld2::onEnterTransitionDidFinish
    ?~~HelloWorld2::onExit
    ?~~ HelloWorld::onEnter
    ?~~ HelloWorld::onEnterTransitionDidFinish
  2. 如果有a和b两个CCScene,b的init,onEnter方法执行都比A的onExit在前,A的dealloc方法是在最后执行了

//-------------------------------------------------------------------------------------------------------------------------------------------

     Script handler auto unregister after onEnter().
    virtual void registerScriptHandler(int nHandler);
    virtual void unregisterScriptHandler(void);

    virtual void addChild(CCNode * child);                           // 添加子节点

    virtual void addChild(CCNode * child, int zOrder);      

    virtual void addChild(CCNode * child, int zOrder, int tag);

    void removeFromParentAndCleanup(bool cleanup);//从父节点移除自己并停止在这个Node上的所有Action

    virtual void removeChild(CCNode* child, bool cleanup);

    void removeChildByTag(int tag, bool cleanup);

    virtual void removeAllChildrenWithCleanup(bool cleanup);//移除该Node所有子节点

    CCNode * getChildByTag(int tag);                               //获取某个node

    virtual void reorderChild(CCNode * child, int zOrder);

    virtual void cleanup(void); //停止所有Schedu

    virtual void draw(void);    //绘图

    virtual void visit(void);     //提交到屏幕

    void transform(void);    //变换坐标

    void transformAncestors(void);

    CCRect boundingBox(void);

    CCAction* runAction(CCAction* action); //运行动作

    void stopAllActions(void);                         //停止所有动作

    void stopAction(CCAction* action);

    void stopActionByTag(int tag);               

    CCAction* getActionByTag(int tag);

    unsigned int numberOfRunningActions(void);

    bool isScheduled(SEL_SCHEDULE selector);  //是否在执行任务

    void scheduleUpdate(void);                                   //执行update任务

    void scheduleUpdateWithPriority(int priority);

    void unscheduleUpdate(void);

    void schedule(SEL_SCHEDULE selector);   //执行指定任务

    void schedule(SEL_SCHEDULE selector, float interval);//定时执行指定任务

    void schedule(SEL_SCHEDULE selector, float interval, unsigned int repeat, float delay);//定时执行指定次数任务

    void scheduleOnce(SEL_SCHEDULE selector, float delay);

    void unschedule(SEL_SCHEDULE selector);//停止任务

    void unscheduleAllSelectors(void);              //停止所有任务

    void resumeSchedulerAndActions(void);   //恢复任务和动作
    void pauseSchedulerAndActions(void);     //暂停任务和动作

    virtual CCAffineTransform nodeToParentTransform(void);//从当前坐标到父容器坐标

    virtual CCAffineTransform parentToNodeTransform(void);//从父容器坐标到当前node坐标

    virtual CCAffineTransform nodeToWorldTransform(void); //从当前node坐标到opengl世界坐标

    virtual CCAffineTransform worldToNodeTransform(void);//从opengl世界坐标到node坐标

    CCPoint convertToNodeSpace(const CCPoint& worldPoint);
    CCPoint convertToWorldSpace(const CCPoint& nodePoint);
    CCPoint convertToNodeSpaceAR(const CCPoint& worldPoint);
    CCPoint convertToWorldSpaceAR(const CCPoint& nodePoint);

    CCPoint convertTouchToNodeSpace(CCTouch * touch);

    CCPoint convertTouchToNodeSpaceAR(CCTouch * touch);
};

NS_CC_END

#endif // __PLATFORM_CCNODE_H__

当执行Set方法执行某种行为,他的所有子节点都会执行

CCLayer 继承CCNode并增加了事件处理

class CC_DLL CCLayer : public CCNode, public CCTouchDelegate, public CCAccelerometerDelegate, public CCKeypadDelegate
{
public:
    CCLayer();
    virtual ~CCLayer();
    bool init();

    static CCLayer *create(void);

    virtual void onEnter();
    virtual void onExit();
    virtual void onEnterTransitionDidFinish();
  //////////////////////////////以下4个方法处理单点触摸 回调    
    virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
    virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);
    virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
    virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent);

//////////////////////////////以下4个方法处理多点触摸  回调

    virtual void ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent);
    virtual void ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent);
    virtual void ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent);
    virtual void ccTouchesCancelled(CCSet *pTouches, CCEvent *pEvent);
   ////////////////////////////下面方法处理传感器回掉
    virtual void didAccelerate(CCAcceleration* pAccelerationValue) {CC_UNUSED_PARAM(pAccelerationValue);}

    /** If isTouchEnabled, this method is called onEnter. Override it to change the    way CCLayer receives touch events.
    ( Default:

   CCTouchDispatcher::sharedDispatcher()->addStandardDelegate(this,0); )
    Example:
    void CCLayer::registerWithTouchDispatcher()
    {
    CCTouchDispatcher::sharedDispatcher()->addTargetedDelegate(this,INT_MIN+1,true);
    }
    @since v0.8.0
    */
    virtual void registerWithTouchDispatcher(void);
   
    /** Register script touch events handler */
    void registerScriptTouchHandler(int nHandler, bool bIsMultiTouches = false, int nPriority = INT_MIN, bool bSwallowsTouches = false);
    /** Unregister script touch events handler */
    void unregisterScriptTouchHandler(void);

    /** whether or not it will receive Touch events.
    You can enable / disable touch events with this property.
    Only the touches of this node will be affected. This "method" is not propagated to it's children.
    @since v0.8.1
    */
    bool isTouchEnabled();
    void setTouchEnabled(bool value);
    /** whether or not it will receive Accelerometer events
    You can enable / disable accelerometer events with this property.
    @since v0.8.1
    */
    bool isAccelerometerEnabled();
    void setAccelerometerEnabled(bool value);
    /** whether or not it will receive keypad events
    You can enable / disable accelerometer events with this property.
    it's new in cocos2d-x
    */
    bool isKeypadEnabled();
    void setKeypadEnabled(bool value);
   
    inline CCTouchScriptHandlerEntry* getScriptHandlerEntry() { return m_pScriptHandlerEntry; };
protected:  
    bool m_bIsTouchEnabled;   //本图层是否处理触摸
    bool m_bIsAccelerometerEnabled;//本图层是否处理传感器
    bool m_bIsKeypadEnabled;//本图层是否处理按键
   
private:
    // Script touch events handler
    CCTouchScriptHandlerEntry* m_pScriptHandlerEntry;
    int  excuteScriptTouchHandler(int nEventType, CCTouch *pTouch);
    int  excuteScriptTouchHandler(int nEventType, CCSet *pTouches);
};

CCScene 是实现对一个整体窗口的根Node

一般使用如下:

CCScene* HelloWorld::scene()
{
    CCScene * scene = NULL;
    do
    {
        // 'scene' is an autorelease object
        scene = CCScene::create();
        CC_BREAK_IF(! scene);

        // 'layer' is an autorelease object
        HelloWorld *layer = HelloWorld::create();
        CC_BREAK_IF(! layer);

        // add layer as a child to scene
        scene->addChild(layer);
    } while (0);

    // return the scene
    return scene;
}