Recently in the development of a cocos2d-x-based landlords card game, in the process of game development to the cocos2d-x engine has a more profound understanding. Now we will give a brief summary of the action processing under the cocos2d-x Engine Based on the implementation process of the sub-card action.
Inside the CCAction architecture has made a good summary, and the blogger an article about the cocos2d-x about the touch event is also more detailed, it is recommended that you take a look.
When it comes to action, the first thing we think of is the movement of the genie. CCMoveTo and CCMoveBy are both subclasses of CCAction. The difference between CCMoveTo and CCMoveBy is that CCMoveTo moves to the specified location based on the parameter, while CCMoveBy indicates the specific length of the move, for example, CCMoveBy * moveBy = CCMoveBy: create (0, ccp (100,100); this statement indicates that the calling Wizard will move 100 in the direction of the X axis (to the right) at the original position, move 100 in the Y axis (up. If it is CCMoveTo, it will move to the point of ccp (100,100.
However, in actual game development, complicated action effects may be used. In this case, we need to combine some objects and use CCSequence and CCSpawn. The two are created in a similar way. They are all created through their static create FUNCTION. parameters are the action objects you need to combine. Note that the last parameter must be NULL. The difference between the two is that CCSequence will execute the uploaded action objects in sequence during building, while CCSpawn will execute the uploaded action objects simultaneously. However, the above two methods are only for the system actions provided by the same genie. Sometimes we need to make one sprite area respond to the action of another genie. That is to say, Genie A needs to complete the action and then notify genie B to execute the corresponding action. The so-called action execution actually calls the step function for each action when each frame is refreshed by CCActionManager to play the action. This article describes the implementation of actions based on frame refresh and is irrelevant to the order added in the code. For example, if you let the three elves execute actions in sequence in the for loop, the engine will not execute the actions because of the order in which your code executes, but every time you execute a for loop, these three genie actions are executed simultaneously. This is back to the question "how to let one Genie notify another genie that I have completed the action, and you have to execute the action.
In the cocos2d-x, four callback function wrappers are provided to help us solve this problem.
Callfunc_selector corresponds to the CCCallFunc class, which is used to encapsulate callback functions without parameters;
CallfuncN_selector, corresponding to the CCCallFuncN class, is used to encapsulate callback functions that pass the CCNode * type pointer containing the parameter that executes the action (in short, whoever runs this action will pass in the address as a parameter );
CallfuncND_selector, corresponding to the CCCallFuncND class. Besides passing CCNode * in point 2nd, we can also pass a void * pointer;
CallfuncO_selector corresponds to the CCCallFuncO class, which is used to encapsulate the callback function that contains a CCObject * parameter;
The preceding four callback function wrappers are introduced mainly because they can be added to CCSequence as a parameter. They can also be added to CCSpawn, however, the action object and function address passed into CCSpawn as parameters will be executed simultaneously, which may produce some unexpected results. Therefore, to ensure that a callback function is executed after an action is executed, you need to add it to CCSequence. Then, how can we implement an action for another genie to execute? In fact, it is very easy to set the address of the function you want to execute as long as the penultimate parameter (the last parameter is NULL of course) in the sequence of actions that the genie needs to execute, after the genie executes all the previous actions, it enters the callback function. In this callback function, you can add the Execution Code of another genie.
The following describes the implementation of special effects on the licensing of landlords.
All the friends who have played mobile phone landlords know that during the licensing process, they will first send cards to the top left and top right players who cannot see the content, and then send a card to the user who can see the specific content, this actually contains at least two genie. The back of a card genie first moves to the top left, then returns to the origin, and then moves to the top right (this can be set to invisible), and then displays the specific card genie (there are actually many, can be placed in a CCArray for maintenance) Move to the user's card selection area below. This process only sends a card to the user. You can use recursive calls to continue licensing until the number of cards is sufficient and then jump out of the function. The specific implementation code is as follows:
[Cpp]
Void GameScene: dispatchCardsCallback (CCNode * pSender, void * args)
{
Switch (int) args)
{
Case 1:
{// Dispath left
MoveBackCard-> setPosition (ccp (m_winSize.width/2, m_winSize.height/2 ));
CCMoveBy * leftMoveBy = CCMoveBy: create (0.1f, ccp (100-m_winSize.width/2, m_winSize.height/2-127 ));
CCSequence * leftSequence = CCSequence: create (leftMoveBy, CCCallFuncND: create (this, callfuncND_selector (GameScene: dispatchCardsCallback), (void *) 2), NULL );
MoveBackCard-> runAction (leftSequence );
Break;
}
Case 2:
{// Dispatch right
MoveBackCard-> setPosition (ccp (m_winSize.width/2, m_winSize.height/2 ));
CCMoveBy * rightMoveBy = CCMoveBy: create (0.1f, ccp (m_winSize.width/2-100, m_winSize.height/2-127 ));
CCSequence * rightSequence = CCSequence: create (rightMoveBy, CCCallFuncND: create (this, callfuncND_selector (GameScene: dispatchCardsCallback), (void *) 3), NULL );
MoveBackCard-> runAction (rightSequence );
Break;
}
Case 3:
{// Dispatch for user
CCMoveTo * moveAction = CCMoveTo: create (0.1f, ccp (100 + (m_mutex + 1) * 30, 70 ));
CCSequence * sequence = CCSequence: create (moveAction, CCCallFuncND: create (this, callfuncND_selector (GameScene: dispatchCardsCallback), (void *) 1), NULL );
If (m_mutex <17 ){
(Dynamic_cast <CardSprite *> (m_array-> objectAtIndex (m_mutex ++)-> runAction (sequence );
} Else {
This-> removeChild (moveBackCard );
This-> removeChild (backCard );
AdjustCard (m_array); // sort card genie
ShowCallScore (); // The display name is "sub Menu ".
}
Break;
}
Default:
Break;
}
}
Void GameScene: dispatchCardsCallback (CCNode * pSender, void * args)
{
Switch (int) args)
{
Case 1:
{// Dispath left
MoveBackCard-> setPosition (ccp (m_winSize.width/2, m_winSize.height/2 ));
CCMoveBy * leftMoveBy = CCMoveBy: create (0.1f, ccp (100-m_winSize.width/2, m_winSize.height/2-127 ));
CCSequence * leftSequence = CCSequence: create (leftMoveBy, CCCallFuncND: create (this, callfuncND_selector (GameScene: dispatchCardsCallback), (void *) 2), NULL );
MoveBackCard-> runAction (leftSequence );
Break;
}
Case 2:
{// Dispatch right
MoveBackCard-> setPosition (ccp (m_winSize.width/2, m_winSize.height/2 ));
CCMoveBy * rightMoveBy = CCMoveBy: create (0.1f, ccp (m_winSize.width/2-100, m_winSize.height/2-127 ));
CCSequence * rightSequence = CCSequence: create (rightMoveBy, CCCallFuncND: create (this, callfuncND_selector (GameScene: dispatchCardsCallback), (void *) 3), NULL );
MoveBackCard-> runAction (rightSequence );
Break;
}
Case 3:
{// Dispatch for user
CCMoveTo * moveAction = CCMoveTo: create (0.1f, ccp (100 + (m_mutex + 1) * 30, 70 ));
CCSequence * sequence = CCSequence: create (moveAction, CCCallFuncND: create (this, callfuncND_selector (GameScene: dispatchCardsCallback), (void *) 1), NULL );
If (m_mutex <17 ){
(Dynamic_cast <CardSprite *> (m_array-> objectAtIndex (m_mutex ++)-> runAction (sequence );
} Else {
This-> removeChild (moveBackCard );
This-> removeChild (backCard );
AdjustCard (m_array); // sort card genie
ShowCallScore (); // The display name is "sub Menu ".
}
Break;
}
Default:
Break;
}
} In the above function, I passed an int variable through callfuncND_selector (which needs to be converted to void *) to identify which player (including the computer and user) to be assigned) to distribute cards. When a user player sends 17 cards, he jumps out of recursion. At the same time, he removes the card genie in the center of the screen and sorts the cards that the user sends, then the sub-menu is displayed to prompt the user to select the sub-menu. Because the beginner cocos2d-x soon, many internal mechanisms on the engine understanding is not very thorough, maybe to achieve this kind of effect there is a better way, welcome everyone to leave a message to correct!