How to Implement MVC in the Cocos2d-x (2)

Source: Internet
Author: User
Tags types of functions

In the previous blog, I mentioned "How to Implement MVC in the cocos2d-x (a)", but, are some pure theoretical things, we need to read some code to understand more clearly. This blog post is based on the previous article, so I suggest you read it first.

Model class

As discussed earlier, the gamemodel class stores some attributes in the game world, such as the current gravity. However, it is also responsible for creating and connecting objects in the game, such as player and platforms. The relationship between them is as follows: (TRANSLATOR: The interface-based programming method is used here. All game objects use the updateable interface, so that you can update yourself in the game loop. At the same time, the gamemodel class provides a factory method creategameobjects to create objects in the game .)

You may have noticed that all model classes implement the updateable protocol and the update method. In this way, they can update their statuses in game loop. For example, in the player class, We need to update the location information of the player based on the current X axis and Y axis speed. In my game, I entrust it to the physics component, which is a simple physical engine I implement. However, if your game is simple, you do not need to separate your physical code, and then you can directly perform collision detection and other physical operations in the update method.

// Player.h#include "cocos2d.h"using namespace cocos2d;class Player : public Updateable{public:void update(ccTime dt){_physics->updateModel(this, dt);// detect collisions with game objects, etc.}}

The update method implemented by gamemodel is not only used to update its own State, but also called the update method of player and the update method of all platforms. This update method will be called by game loop later.

// GameModel.h#include "cocos2d.h"using namespace cocos2d;class GameModel : public Updateable{public:virtual void update(ccTime dt){// modify game model properties here   // update playerthis->player->update(dt);// update platformsfor(int i=0; i<_platforms.size(); i++){_platforms.at(i)->update(dt);}// ...}}

Views and controllers

Each scenario in my game is associated with a controller class that handles user interaction, creates views, and jumps to management scenarios. The Controller will schedule a main loop of the game. In this loop, all the update Methods of the model and view will be called.

// GameplayController.h#include "cocos2d.h"using namespace cocos2d;class GameplayController : public GameplayViewDelegate{public:virtual bool init() {GameplayView *view = new GameplayView();view->initWithDelegate(this);// retain view in controllerthis->view = view;// release viewview->release();// init modelGameModel *model = GameModel::sharedModel();model->createGameObjects();model->getPlayer()->run();this->scheduleUpdate();return true;}void update(ccTime dt) {GameModel *model = GameModel::shareMode();if(model->getIsGameover()) {CCDirector::sharedDirector()->replaceScene(GameOverController::node());// process modelmodel->update(dt);// update viewthis->view->update(dt);}}}

View is mainly responsible for rendering game images based on the model status. However, because of the cococs2d implementation method, we also need to pass the touch event to the Controller class. You should note that the view does not directly depend on the controller. The View class calls the controller through the gameviewdelegate protocol. This is why we need to pass a delegate in the init method.

// GameplayView.h#include "cocos2d.h"using namespace cocos2d;class GameplayView {public:void initWithDelegate(CCObject *theDelegate) {this->delegate = theDelegate;// initialize layers _backgroundLayer = GameplayBackgroundLayer::node();this->delegate->addChild(_backgroundLayer);_platformLayer = GameplayPlatformLayer::node();this->delegate->addChild(_platformLayer);_playerLayer = GameplayPlayerLayer::node();_playerLayer.delegate = theDelegate;this->delegate->addChild(_playerLayer);_hudLayer = GameplayHudLayer::node();_hudLayer.delegate = theDelegate;this->delegate->addChild(_hudLayer);}}

Update: I forgot to tell you how the layer is implemented. In fact, it is very easy to create some Sprite, action and animation.

// GameplayPlayerLayer.h#include "cocos2d.h"using namespace cocos2d;class GameplayPlayerLayer : public CCLayer, public Updateable{public:virtual bool init() {this->setIsTouchEnabled(true);this->setIsAccelerometerEnabled(true);// ResourceManager is the self-declared classResourceManager *resources = ResourceManager::sharedResourceManager();CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(PLAYER_SPRITE_SHEET_PLIST);CCSpriteBatchNode *spriteSheet = resources->playerSpriteSheet;this->addChild(spriteSheet); // ...      // initialize sprites     // initialize animations}// ...}

The genie in the layer will be updated in the update method of the layer, as shown below:

void update(ccTime dt){// update player sprite based on modelGameModel *model = GameModel::sharedModel();_playerSprite->setPosition(ccp((model->getPlayer()->getPosition().x - model->getViewPort()->getRect()->getOrigin().x)*PRM_RATIO, model->getPlayer()->getPosition().h - model->getViewPort()->getRect()->getOrigin().y)*PRM_RATIO);}

Note: When rendering the player position, we use ppm_ratio to convert meters into point. (Why is it point instead of pixel, because cocos2d uses point instead of pixel. If you do not understand it, please refer to the source code and official documentation)

The Touch event is passed to the Controller class as follows:

class GameplayPlayerLayer : public CCLayer, public Updateable{// ...virtual void ccTouchesBegan(CCset *pTouches, CCEvent *pEvent){this.delegate->playerBeginJump();}}

Then there is a complete UML diagram of the interaction between the view and the controller:

Process Model events

In the previous blog, I left a problem: how to deal with the interaction between the model and the Controller. The others are very simple, that is, the observer mode. The controller only needs to subscribe to model events and then define corresponding processing methods. When the model is updated, an event is triggered, and the Controller that listens to the event is notified. The following is an implementation: (TRANSLATOR: many children's workers do not know how to interact between objects. In fact, using notification can greatly decouple the interaction between objects, making the code easier to maintain .)

Class player: Public updateable {public: void beginjump () {// There is an nsicationcenter center class in object-C. You must implement the notificationcenter: sharecenter () class in C ++ () -> postnotificationname (event_player_begin_jump, null );}}

The Controller subscribes to events. when an event occurs, it will be notified and the corresponding event processing function will be called.

class GameplayController : public GameplayViewDelegate{public:virtual bool init() {NotificationCenter::shareCenter()->addObserver(this, callfunc_selector(GameplayController::onPlayerBeginJumpNotification), EVENT_PLAYER_BEGIN_JUMP, NULL);//...}void onPlayerBeginJumpNotification(){SimpleAudioEngine::sharedEngine()->playEffect(PLAYER_JUMP_SOUND);}}

That's all!

At first glance, it may be a bit complicated. In addition, it is a bit difficult to create so many types of functions to implement a simple function. Besides, do you still remember? If you add too many classes to the system, it is actually an anti-pattern called fear of adding classes. However, in the long run, it is worthwhile to add so many classes from the maintainability perspective. I will show you the following tutorials. If you have better ideas on how to use MVC in cocos2d, please add.

 

Reference Source: http://www.cnblogs.com/andyque/archive/2012/03/11/2390082.html

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.