The clever use of cocos2d-x delegated mode-with source code (2), the clever use of cocos2d-x
For more information, see http://blog.csdn.net/hust_superman/article/details/38292265, thank you.
Following the specific implementation of the delegate class in the previous article, this article describes how to use the implemented delegate class in the game. That is, how to call the delegate class in the game to complete some functions. The specific application scenarios and application layers are described below.
Let's take a look at the specific image of the game demo implementation. The demo is relatively simple, but the resources are complete. After obtaining the source code, we can continue to improve the demo to make a real game. Okay, old rules. Let's talk about it first:
After you click the play button in the game, the game's main interface is displayed. You can see a small red square slowly moving to the bottom of the page. The game ends and an ending page is displayed.
This demo mainly explains how to use the delegate class to make the main game logic clearer in the game.
Now let's take a look at the specific scenarios and the main layers of the game.
In a GameScene scenario in the game, the delegate StatusLayer layer and the GameLayer layer are added to the game main logic. In the GameLayer layer, the delegate class is called to complete the logic of Game start and end.
The following describes the implementation of GameScene. cpp, in which the delegate class is registered to the GameLayer layer.
#include "GameScene.h"#include "GameLayer.h"#include "StatusLayer.h"USING_NS_CC;GameScene::GameScene(){}GameScene::~GameScene(){}bool GameScene::init() {if(Scene::init()) {
<Span style = "white-space: pre"> </span> // loads image resources to the cache to facilitate later use of image resources SpriteFrameCache: getInstance () -> addSpriteFramesWithFile ("flappyrec. plist "," flappyrec.png "); auto statusLayer = StatusLayer: create (); this-> addChild (statusLayer); // Add the main game layerauto gameLayer = GameLayer :: create (); // register the delegate class to the GameLayer layer. Set setDelegator (statusLayer); this-> addChild (gameLayer); return true;} else {return false ;}}
In GameScene, The StatusLayer and GameLayer layers are added, and StatusLayer is registered as the delegate class to GameLayer.
The main things in the game are all in GameLayer. Let's take a look at the contents of GameLayer. h.
# Include "cocos2d. h "USING_NS_CC; // game status enumeration class typedef enum _ game_status {GAME_STATUS_READY = 1, GAME_STATUS_START, GAME_STATUS_OVER} GameStatus;/*** abstract delegate class, there are three virtual functions. to inherit the sub-classes of this delegate class, you need to implement the * virtual functions to control the start, running, and end judgment of the game */class StatusDelegate {public: /*** When the game start, this method will be called */virtual void onGameStart () = 0;/*** During paying, after the score changed, this method will be called */virtual vo Id onGamePlaying () = 0;/*** When game is over, this method will be called */virtual void onGameEnd () = 0 ;}; const int MENU_START = 10001; class GameLayer: public Layer {public: GameLayer ();~ GameLayer (); virtual bool init (); CREATE_FUNC (GameLayer); // implement the macro for registering the delegate class. delegator is used as the member variable, you can call each function in the delegate class // override the onEnter function of the parent class. Remember to use the overridevirtual void onEnter () // macro to register the delegate class. The delegator is used as the member variable, you can call each function override in the delegate class; // implement the macro for registering the delegate class. The delegator acts as a member variable and can call each function CC_SYNTHESIZE (StatusDelegate *, delegator, Delegator) in the delegate class; private: void showStartButton (); // display the start button void menuStartCallback (Ref * pSender); // the start button callback function void createSquares (); // create the red block void moveFinished (Ref * pSender); // The Block Moving End function private: Sprite * square; Size visibleSize; Point origin; GameStatus gameStatus ;};
The most important thing in the above Code is the use of the delegate class macro.
// Register the delegate class to the GameLayer layer, where gameLayer-> setDelegator (statusLayer );
The role of a macro is to register it with the StatusDelegate subclass of the specific delegate class in GameLayer.
The following describes the specific implementation of GameLayer. cpp.
# Include "GameLayer. h" USING_NS_CC; GameLayer: GameLayer () {} GameLayer ::~ GameLayer () {} bool GameLayer: init () {if (! Layer: init () {return false;} this-> gameStatus = GAME_STATUS_READY; visibleSize = Director: getInstance ()-> getVisibleSize (); origin = Director :: getInstance ()-> getVisibleOrigin (); // call the show start button this-> showStartButton (); return true;} void GameLayer: onEnter () {Layer :: onEnter (); // TODO}/*** display the start button and register the callback function */void GameLayer: showStartButton () {Sprite * startBtn = Sprite :: crop ("play.png"); Sprite * startBtnActive = Sprite: createWithSpriteFrameName ("play.png"); startBtn-> setScale (0.6f); // scale startBtnActive-> setScale (0.6f ); // scale startBtnActive-> setPositionY (4); // move the button up to four units. // Add the above genie as the menu to auto menuStartItem = MenuItemSprite: create (startBtn, startBtnActive, NULL, CC_CALLBACK_1 (GameLayer: menuStartCallback, this); auto menuStart = Menu: create (menuStartItem, NULL); menuStart-> setPosition (Vec2 (this-> visibleSize. width/2, this-> visibleSize. height/2); menuStart-> setTag (MENU_START); this-> addChild (menuStart, 10);}/*** the callback function after pressing the Start Menu, the main function is to call the onGameStart function in the delegate class to start the game. * remove the start button and create a red box */void GameLayer: menuStartCallback (Ref * pSender) on the main page of the game) {if (this-> gameStatus = GAME_STATUS_OVER) {return;} if (this-> gameStatus = GAME_STATUS_READY) {log ("start "); // delegate the onGameStart function in StatusLayer to execute the game start logic. this-> delegator-> onGameStart (); this-> getChildByTag (MENU_START)-> runAction (FadeOut :: create (0.4f); this-> removeChildByTag (MENU_START, true); this-> gameStatus = GAME_STATUS_START; this-> createSquares (); // create a red small square} else if (this-> gameStatus = GAME_STATUS_START) {// TODO}/*** create a red small square, and move the Game 5 seconds later */void GameLayer: createSquares () {// Add the square genie square = Sprite: createWithSpriteFrameName ("whitebird.png "); square-> setPosition (Vec2 (visibleSize. width/2, visibleSize. height/2); square-> setColor (Color3B: RED); this-> addChild (square); // starts the game. After 5 seconds, the game ends. auto move = MoveTo:: create (5.0f, Vec2 (square-> getPositionX (), origin. y); // callback function auto moveDone = CallFuncN: create (CC_CALLBACK_1 (GameLayer: moveFinished, this) after the move ends); auto sequence = Sequence: createWithTwoActions (move, moveDone); square-> runAction (sequence);}/*** the callback function after the move ends, that is, the game ends, * You can use delegator-> onGameEnd. * This is to directly use the onGameEnd of the delegate class to control the end of the game. * does the class instantly feel much clearer? */void GameLayer :: moveFinished (Ref * pSender) {// delegate the onGameEnd function in StatusLayer to execute the game end logic this-> delegator-> onGameEnd (); this-> removeChild (square, true );}
In the code above, the delegate class calls the onGameStart () function and the onGameEnd () function, both of which use the macro of the delegate class described earlier.
CC_SYNTHESIZE(StatusDelegate*,delegator,Delegator);
Directly Using delegator to call functions in the delegate class is equivalent to implementing communication between layers.
// Delegate the onGameEnd function in StatusLayer to execute the game end logic this-> delegator-> onGameEnd ();
The above code is the main expression of this blog post. When you have implemented all the specific delegate classes, in the main logic of the game, you will find that the code can be called so easily, clearly, and efficiently, and the code logic is so simple, because you have implemented it in the delegate class.
Well, this article and the previous article express the specific implementation of the delegate class. With a good delegate class, the main logic of the game can be clearer, in addition, parameters can be transferred between the game layer and layer to avoid the use of static variables and simplify the code volume of the main game layer, which is not so bloated.
The demo source code is attached below. The Source Code contains specific resource files. After downloading the source code, you can create a new project to complete the game and implement this game.
: Click to download
Well, this article mainly focuses on the specific application of the delegate class. The next article describes the application of the physical collision rules in the game.
Production of ordinary applications (non-game) is not suitable for the use of cocos2d-x, will it lead to low development efficiency
Cocos2d-x is just a game framework, and you are not finding a better cross-platform engine that suits you better while choosing it, even if there are PhoneGap, Unity and so on.
It provides very few controls, and I don't think the development efficiency is higher than the development efficiency of the two methods, without computing the learning cost.
I think you hire two engineers familiar with cocos2d-x development than recruiting an android, an iOS engineer is expensive.
Personal Opinion
How to pause and resume the game in cocos2d-X ?? Source code
The director class has its own method. pause () and resume () are used to pause and resume the game.