cocos2d meets MVC – Implementing simple board game part 1

This is a first part of a series of posts that aim to help to understand how we can build a game in cocos2d using MVC pattern (or its variation adapted to cocos2d programming model). This is a follow up post to the previous posts that I wrote some time ago so if you haven’t read it before I suggest to at least read the first part which explains a bit of a theory.

Scenario

We are going to build a simple “framework” for building board puzzle games. This framework will be used in my new game and its core functionalities are as follows:

  1. A game board is defined by a number of rows and columns, which may vary for different application levels.
  2. The game board stores game pieces, and each game board’s space can contain only one game piece.
  3. The game board can be initialized with a number of “fixed” game pieces that cannot be moved by a player during the game.
  4. A toolbox is defined by a number of toolbox items that represents slots for movable game pieces.
  5. Toolbox item (slot) can contain many toolbox items of the same type.
  6. Game pieces can be moved from the toolbox item (slot) and put on the game board.

GameBoard example

Basic concepts

From wikipedia:

The model manages the behaviour and data of the application domain, responds to requests for information about its state (usually from the view), and responds to instructions to change state (usually from the controller). In event-driven systems, the model notifies observers (usually views) when the information changes so that they can react.

The view renders the model into a form suitable for interaction, typically a user interface element. Multiple views can exist for a single model for different purposes. A viewport typically has a one to one correspondence with a display surface and knows how to render to it.

The controller receives user input and initiates a response by making calls on model objects. A controller accepts input from the user and instructs the model and a viewport to perform actions based on that input.

Following the definition from wikipedia we can identify the following main classes (we will add the model later on):

  1. GameBoardView that represents the main view of an application,
  2. GameBoardController that represents a controller for GameBoardView.

GameBoardController & GameBoardView relationship

Please notice that the solid line represents a direct association (controller holds a reference to the view), the dashed line is an indirect association (via observer). The indirect association will be used later on to implement touches.

Implementation

Project structure

After creating a new project in XCode 4 based on a default cocos2d template we create the following groups:

  1. View – views & controller classes (you can also divide it into two different groups but I like to keep it in the same place as those classes are tightly connected).
  2. Model – we will use it later for storing model classes.
MVC - project structure

 

GameBoardView implementation

We start with GameBoardView implementation. We make GameBoardView extend CCNode.

@interface GameBoardView : CCNode {
}

Then we implement init method of GameBoardView and we do some drawing here to check if everything works fine.

- (id)init {
    if ((self = [super init])) {
        // create and initialize a Label
	CCLabelTTF *label = [CCLabelTTF labelWithString:@"Hello World from view" fontName:@"Marker Felt" fontSize:48];
 
	// ask director the the window size
	CGSize size = [[CCDirector sharedDirector] winSize];
 
	// position the label on the center of the screen
	label.position =  ccp( size.width /2 , size.height/2 );
 
	// add the label as a child to this Layer
	[self addChild: label];
    }
 
    return self;
}

GameBoardController implementation

GameBoardController is responsible for initializing the view. It also holds a reference to GameBoardView for future needs.

@interface GameBoardController : CCNode {
    GameBoardView *view;
}

Because GameBoardController extends CCNode we can add GameBoardView as a child of GameBoardController.

- (id)init {
    if ((self = [super init])) {
        view = [GameBoardView node];
 
        [self addChild:view];
    }
 
    return self;
}

Final modifications

We modify AppDelegate and we run our newly created controller:

[[CCDirector sharedDirector] runWithScene: [GameBoardController node]];

And here it is for now. When you run your project the effect should be quite similar to default cocos2d template behavior. The difference is that we created a part of MVC project skeleton ready to implement necessary application logic.

Next steps

The project structure at this point is ready to introduce more advanced concepts:

  1. Handling touches.
  2. Introducing model.
If you are interested how I am going to approach it please follow my next #iDevBlogADay post in two weeks. Follow me @bwilczyn to get the latest updates and notification about a new post.
Be Sociable, Share!
This entry was posted in idevblogaday, iPhone and tagged , , , , , , , , , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

6 Comments

  1. Posted October 21, 2011 at 9:09 pm | Permalink

    Really excited to see this multi-parter and looking forward to following. I constantly crave for more MVC in my cocos2d.

    Question : Should the Controller really be a CCNode or should it be composed of one instead?

    If we are trying to mimic the UIViewController style, I’m inclined to argue it should be composed of a view rather than be a view that includes game logic.

    • Posted October 22, 2011 at 1:12 pm | Permalink

      Thanks for your feedback. Second part of this tutorial will definitely bring more details and clarify some missing parts.

      Regarding your question – I try to keep a balance between implementation purity and simplicity. I believe there is nothing wrong with the controller being a CCNode (CCNode doesn’t really represent a view – it’s just a container IMHO) and as you can see implementing it this way really makes it much simpler (see AppDelegate implementation for an implementation of controller & view instantiation).

      What’s more – I am not going to implement any view-specific logic inside a Controller. Controller in my implementation actually contains a view and not extend it so the separation of concerns is preserved.

  2. El Severo
    Posted February 8, 2012 at 12:03 pm | Permalink

    @Bartek: Really good articles here, thanks for them!
    I’d like to ask you also about applying correctly the MVC pattern to my game;

    My scenario sounds something like this: A find object game with parallax effect and placed objects (ccmenuitems in my case, for some reasons) on each layer of the parallax;

    How the MVC patter will be applied ? Right now parallax1 & parallax2 layers are added to a layer as a child and that layer and that one is added to the game play layer with the HUD layer.

    • Posted February 9, 2012 at 11:31 pm | Permalink

      Parallax1 & parallax2 from what I hear is a view and you should keep it there.

      • El Severo
        Posted February 13, 2012 at 5:20 pm | Permalink

        Thanks for reply!

        Can you add some sample project?

  3. arun
    Posted March 24, 2012 at 1:30 pm | Permalink

    I’m designing a simple demo game for my practice, could you guide me for this development.
    Game is bagchal(Tiger Vs Goat or Angry Tiger) After this demo i completed i’ve one idea to design the game similar to this but quite a bit more interesting is included, could you please help me to develop a game, Hope you do so my email is arungre@hotmail.com

2 Trackbacks

  1. [...] XPerienced Blog iPhone development from .NET developer perspective Skip to content AboutContactApps « cocos2d meets MVC – Implementing simple board game part 1 [...]

  2. [...] cocos2d meets MVC part 1, [...]

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">