Implementing MVC pattern for cocos2d-x projects

Original article can be found here: http://cobagames.com/2013/12/15/implementing-mvc-pattern-for-cocos2d-x-projects/
Full solution to this framework can be downloaded from GitHub: https://github.com/cobagames/mvcsample)

To understand this article a working knowledge of the cocos2d-x framework is required. As mentioned in my earlier post “Road to cobagames part 2″, I came across a wonderful book which explained how to implement cocos2d in the MVC pattern. Since the team decided to go with cocos2d-x path, I decided to use my existing knowledge of this implementation pattern. Trust me, if you want to scale your game, you will want to implement this. For simple games, probably this does not matter as much (but you never know until you have finished your game :slight_smile: ).
<div style=”float:left;width:30; margin-right:20px;">
!http://cobagames.files.wordpress.com/2013/12/mvc.png?w=750!
</div>

*+A short description on the MVC pattern+*

The *Controller* sends a command to the model to update the model’s state. It can also send commands to it’s associated view to change the views’s presentation of the model.
The *Model* notifies it’s associated views and controllers when there has been a change in the state. This notification allows the views to produce an updated output and the controllers to change the available set of commands.
The *View* requests information from the model that it needs for generating an output representation to the user.

<div style=“clear:both;”></div>

Now we implement this pattern for cocos2d-x framework. I will create a simple x-code project to demonstrate the implementation. This sample has a ‘background’, a ‘ball’ and a ‘collision’ animation. The ball will bounce all over the background randomly. When the ball hits the ground, it will create a collision animation on the point of contact to the ground. Player can swipe/touch the ball to get rid off it.
In this scene, we have just the three “game objects”, a background, a ball and a collision animation. These objects are considered as model. Background is simple, it does not have any states or actions. This just combines with the ball and the collision object to present to the view.

cocos2d-x class CCLAYER acts as a controller here. When the user interacts with the screen, it sends a message to the controller, which in return sends a command to the model according to either instructions from the user, or planned game steps (like bounce the ball).

<div>
!http://cobagames.files.wordpress.com/2013/12/cocos2d-x-mvc1.png?w=750!
</div>
*Model:* The Ball and the Collision class contains information about themselves. It has no idea what is happening in the *controller * class. For example, the ball knows how to bounce and it will do so when asked. In the MVC pattern, model cannot access the controller directly, but it can inform the controller that it has finished the task that it was suppose to do. The way this can be achieved is through a delegate control.

In this example, when the ball finishes bouncing, the *view* needs to show a collision animation. The ball informs the game layer class through a *delegate control* that it has finished bouncing, and therefore the layer requests the collision class to animate at the same time.

*The game layer requests the ball to bounce*

<pre>
Ball* ball = Ball::create();
ball->setDelegate(this);
ball->initWithSpriteFrame(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(“ball_1.png”));
ball->setPosition(spawnLocation);
ball->setInitialPosition(spawnLocation);
ball->changeState(kStateBouncing);
_sceneSpriteBatchNode->addChild(ball, ZValue, kBallTagValue);
</pre>

*The ball bounces*

<pre>
CCJumpTo *jumpTo = CCJumpTo::create(1.5f, this->getInitialPosition(), this->getPositionY() + getScreenSize().height/2, 1.0);
CCSequence *sequence = CCSequence::create(jumpTo, CCCallFuncN::create(this, callfuncN_selector(Ball::bounceMe)) ,NULL);
this->runAction(sequence);
</pre>
*The ball updates the game layer that it has finished bouncing*

<pre>
this->getDelegate()->touchGround(this->getPosition());
</pre>

*The game layer knows that the ball has finished bouncing and then it requests the collision to animate at the position where the ball had finished bouncing*

<pre>
void GamePlayLayer::touchGround(CCPoint startPosition){
Collision *collision = Collision::create();
collision->initWithSpriteFrame(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(“collision_1.png”));
collision->setPosition(startPosition);
collision->changeState(kStateTapped);
_sceneSpriteBatchNode->addChild(collision, ZValue, kBallTagValue);
}
</pre>
*The Collision class the receives command to animate, which it obeys*

<pre>
CCSequence *sequence = CCSequence::create(CCAnimate::create(getAnim()), CCCallFuncN::create(this, callfuncN_selector(Collision::removeAndClean)) ,NULL);//finish animation and remove the sprite.
this->runAction(sequence);
</pre>

*The user taps at the ball to kill it*

<pre>
void GamePlayLayer::ccTouchesBegan(CCSet *touches, CCEvent *event){
CCTouch* touch = (CCTouch*)touches->anyObject();
Ball* ball = (Ball*)_sceneSpriteBatchNode->getChildByTag(kObjectTypeBall);
if (ball != NULL && ball->boundingBox().containsPoint(touch->getLocation())) {
ball->stopAllActions();
ball->changeState(kStateTapped);
this->createObjectOfType(kObjectTypeBall, 5, ccp(getScreenSize().width/2,getScreenSize().height/8.0), kZValue);
}
}
</pre>
*Full solution to this framework can be downloaded from GitHub: https://github.com/cobagames/mvcsample*

This solution contains a rough implementation of the MVC pattern for the cocos2d-x framework. In the start it looks like we have complicated things, but trust me, when the project gets bigger and you have 100′s of sprites to manage, coding becomes very simple and manageable if you follow ‘a’ pattern (not just necessarily this one). This pattern is working great for me and I have fully implemented this in my upcoming Game ‘Masato’.

Please comment below and let me know your thoughts around it. There is always room for improvements.

*Here is a video to demonstrate the end result.*

*References:*

http://en.wikipedia.org/wiki/ModelE2��view–controller
http://www.informit.com/store/learning-cocos2d-a-hands-on-guide-to-building-ios-games-9780321735621