A game full of action, adventure and puzzle where Masato needs to protect his village from one of the most powerful rogue ninja he as ever faced

Post tutorial Report RSS Implementing MVC framework for cocos2d-x projects

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

Posted by on - Advanced Design/Concepts

Implementing MVC pattern for cocos2d-x projects

(Full solution to this framework can be downloaded from GitHub)
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 :) ).

cocos2d-x MVC pattern

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.

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).

cocos2d-x MVC pattern

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

cpp code:
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);

The ball bounces

cpp code:
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);

The ball updates the game layer that it has finished bouncing

cpp code:
this->getDelegate()->touchGround(this->getPosition());

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

cpp code:
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);
}

The Collision class the receives command to animate, which it obeys

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

The user taps at the ball to kill it

cpp code:
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);
}
}

Full solution to this framework can be downloaded from GitHub

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:

Post comment Comments
AraVin:D
AraVin:D - - 155 comments

Nice Looks like u guys been workin out :)

Reply Good karma Bad karma+2 votes
cobagames Author
cobagames - - 35 comments

What do you think? Is this useful?

Reply Good karma+1 vote
cobagames Author
cobagames - - 35 comments

Haha, thanks!! It is full on!!

Reply Good karma+1 vote
Post a comment

Your comment will be anonymous unless you join the community. Or sign in with your social account: