Principle of cocos2d-x action

Source: Internet
Author: User

First, ccaction is the base class of all actions, such as the inheritance relationship:

 

Let's take a look at the definition of ccaction:

class CC_DLL CCAction : public CCObject {public:    CCAction(void);    virtual ~CCAction(void);    const char* description();    virtual CCObject* copyWithZone(CCZone *pZone);    //! return true if the action has finished    virtual bool isDone(void);    virtual void startWithTarget(CCNode *pTarget);        virtual void stop(void);    //! called every frame with it‘s delta time. DON‘T override unless you know what you are doing.    virtual void step(float dt);    virtual void update(float time);       inline CCNode* getTarget(void) { return m_pTarget; }    inline void setTarget(CCNode *pTarget) { m_pTarget = pTarget; }        inline CCNode* getOriginalTarget(void) { return m_pOriginalTarget; }     inline void setOriginalTarget(CCNode *pOriginalTarget) { m_pOriginalTarget = pOriginalTarget; }    inline int getTag(void) { return m_nTag; }    inline void setTag(int nTag) { m_nTag = nTag; }public:    static CCAction* create();protected:    CCNode    *m_pOriginalTarget;    CCNode    *m_pTarget;    int     m_nTag;};

There are three member variables at the end of the class definition, and the ccfinitetimeaction inherited from ccaction mainly adds a member variable float m_fduration to save the total completion time of the action;

For its two subclasses ccactioninstant and ccactioninterval, the former does not add any functions and variables, while the latter adds two member variables: Float m_elapsed (record the elapsed time from the beginning of the action ); and bool m_bfirsttick (a control variable );

 

How is the action executed?

When a node calls the runaction method, the action management class ccactionmanager (Singleton class) adds new actions and nodes to its managed action table.

CCAction * CCNode::runAction(CCAction* action){    CCAssert( action != NULL, "Argument must be non-nil");    m_pActionManager->addAction(action, this, !m_bRunning);    return action;}

 


In addaction, after an action is added to the action queue, the member function startwithtarget (ccnode * pTARGET) of the action is called to bind the execution node of the action, and initialize the member variables of the category class.

 

After all this work is done, the system will traverse every action in the action table in ccactionmanager and call the action step (float) method when the screen is refreshed every frame. The step method is mainly responsible for calculating the m_elapsed value and calling the update (float) method.

void CCActionInterval::step(float dt){    if (m_bFirstTick)    {        m_bFirstTick = false;        m_elapsed = 0;    }    else    {        m_elapsed += dt;    }        this->update(MAX (0,                // needed for rewind. elapsed could be negative                      MIN(1, m_elapsed / MAX(m_fDuration, FLT_EPSILON)   // division by 0                          )                      )                 );}

The float parameter passed in the update method represents the ratio of the elapsed time to the time required for the completion of the action, between 0 and 1, that is, the percentage of completed actions. Then, in the update method, the node attributes are operated by the ratio to achieve the effect of the action.
For example, when moveBy calls update, it calls setposition through the introduced proportion to directly modify the node attributes.

After each frame ends, update of ccactionmanager checks whether the isdone function of each action in the Action queue returns true. If true is returned, the action ends and is deleted from the queue.

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

 

As shown above, actions are managed by ccactionmanager. Let's take a look at the working principle of ccactionmanager.

During ccdirector initialization, the following code is executed:

    // scheduler    m_pScheduler = new CCScheduler();    // action manager    m_pActionManager = new CCActionManager();    m_pScheduler->scheduleUpdateForTarget(m_pActionManager, kCCPrioritySystem, false);

It can be seen that the action management class registers the update timer when it is created, so the ccscheduler will trigger the update (float) method registered by ccactionmanager in every mainloop update frame of the game. See this link for how scheduler works: http://www.cnblogs.com/songcf/p/3162414.html

 

// Main loopvoid ccactionmanager: Update (float DT) {// each node in the enumerated action table for (thashelement * ELT = m_ptargets; ELT! = NULL;) {m_pcurrenttarget = ELT; m_bcurrenttargetsalvaged = false; If (! M_pcurrenttarget-> paused) {// The actions array of each action of the enumeration node may be modified in the loop for (m_pcurrenttarget-> actionindex = 0; m_pcurrenttarget-> actionindex <m_pcurrenttarget-> actions-> num; m_pcurrenttarget-> actionindex ++) {m_pcurrenttarget-> currentaction = (ccaction *) m_pcurrenttarget-> actions-> arr [m_pcurrenttarget-> actionindex]; If (m_pcurrenttarget-> currentaction = NULL) {continue;} m_pcurrenttarget-> currentactionsalvaged = false; m_pcurrenttarget-> currentaction-> step (DT); If (m_pcurrenttarget-> currentactionsalvaged) {// The currentaction told the node to remove it. to prevent the action from // accidentally deallocating itself before finishing its step, we retained // It. now that step is done, it's safe to release it. m_pcurrenttarget-> currentaction-> release ();} else if (m_pcurrenttarget-> currentaction-> isdone () {m_pcurrenttarget-> currentaction-> stop (); ccaction * paction = m_pcurrenttarget-> currentaction; // make currentaction nil to prevent removeaction from salvaging it. m_pcurrenttarget-> currentaction = NULL; removeaction (paction);} m_pcurrenttarget-> currentaction = NULL; }}// ELT, at this moment, is still valid // so it is safe to ask this here (Issue #490) ELT = (thashelement *) (ELT-> Hh. next); // only delete currenttarget if no actions were scheduled during the cycle (Issue #481) if (m_bcurrenttargetsalvaged & m_pcurrenttarget-> actions-> num = 0) {deletehashelement (m_pcurrenttarget) ;}// issue #635 m_pcurrenttarget = NULL ;}

Principle of cocos2d-x action

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.