How to implement MVC pattern in cocos2d game

MVC patternModel-View-Controller (MVC) is a widely adopted pattern for handling user interface interactions in web based applications. Web development stacks such as Ruby On Rails, Django or ASP.NET MVC are different approaches to MVC in web development on different platforms, but all of them share the same main principle – separation of domain logic from the user interface. Separation of concerns (SoC) is one of the most important concepts in today software architecture – not digging down into details this concept states that a given problem involves different kinds of concerns, which should be separated in order to achieve better code reusability, robustness, adaptability and maintainability. All of those are important indicators of code / software quality.

Cocos2d isn’t build around a concept of MVC, but nothing prevents you from building your own MVC stack around Cocos2d in your game. There might be different approaches to this problem, in this blog post I will share with you how I have implemented MVC pattern in my game (which I hope to release soon).

Problem

Cocos2d classes such as CCSprite, CCLayer, CCScene are all subclasses of CCNode. The most naive implementation of a game in Cocos2d has the following processes operating with each other to implement game logic:

  1. CCScene is instantiated by application delegate,
  2. CCScene instantiates one or more CCLayer and add it as yours children,
  3. CCLayer instantiates one or more CCSprite,
  4. CCScene handles user input (touch events or accelerometer changes) and updates CCLayer / CCSprite properties (such as position) accordingly, or executes different CCAction to handle more complex object behaviors,
  5. CCScene runs a game loop to udpate CCLayer / CCSprite properties in discrete intervals of time (for example, 60 times per second).

It looks very simple and it’s the easiest way to start implementing your game but sooner or later, when your game logic  grows, your code becomes more and more difficult to maintain. The problem with this approach is that CCScene is responsible for too many things – user interaction, application logic and presentation.

The model

MVC separates different view-related concerns into the following components:

  • Model which is responsible for domain logic,
  • View which is responsible for presentation,
  • Controller which is responsible for handling user input.

Let’s begin with a model. Model represents a game logic. I am building a platform game so I will keep my examples based on actual implementation. My model contains the following classes (just some of them):

  • Player,
    • Contains properties such as: player position, player current velocity (in X / Y axes), etc.
    • Contains methods that execute domain logic on a player, such as run, walk, jump, etc.
    • Contains a method called update that is executed in a main game loop and is responsible for updating a player model in time.
  • Platform,
    • Contains properties such as: platform position, platform width, platform height, etc.
    • Contains methods that execute domain logic on a platform, such as collapse,
    • Contains a method called update that is executed in a main game loop and is responsible for updating a platform in time.
  • GameModel,
    • Contains properties that describe a world all other objects live in, such as current gravity,
    • Contains methods that execute domain logic on a game model,
    • Contains a method called update that is executed in a main game loop and is responsible for updating a game world properties but also trigger update on the other objects that live in a game world.

You may ask: isn’t it an unnecessary duplication of properties that you can normally find in CCSprite (such as position, width, height etc.)? I will say: yes and no. Yes, because it looks quite similar and no, because model is using different units than pixels which better reflect the reality of a real world – in a model I am using meters but you can also use inches or any others you prefer. Model is completely unaware of a rendering engine that you are going to use later on.

The view

According to MVC principle the view should be only responsible for a presentation. It’s actually the easiest part of MVC in cocos2d. If you have a model you can just render it by CCLayer using CCSprite or other Cocos2d classes. The benefit of having a model separated from a view is that you don’t need to map properties of a model directly to view properties, for example if your player is changing your position in X axis, but you want to keep it always 10 px from the left of a screen, instead of moving a player’s sprite you would just rather move a whole CCLayer instead. When rendering model objects into view you need to remember about the units, if you are using meters you should remember that you should convert it to pixels (if your case is the same as mine you will most probably have a constant meters to pixel ratio as I do). How does your model take the view? You can either pass it from the controller when a view is created or you can create a game model as a singleton and access it using a static method.

The controller

The controller ties everything together and its main responsibility is a user input handling. Since I need to instantiate a model and a view somewhere I find it best to do it in a controller. I also implement my controller as a subclass of CCScene and I have my initial controller instantiated by my application delegate class. There is however one problem here – touches are handled by CCLayer class which in my approach is a view. Because I don’t want a view to be responsible for handling user input I need to pass a view a reference to a controller (not directly, but as a delegate) and execute controller method (through a delegate) from a touch handler in view. And that’s it – my controller is now fully responsible for handling a touch event from a view and modify a model accordingly (either by updating model properties or by executing model methods). After I modify a model, the view needs to be updated as well. I do it in my game loop, which is implemented by a controller. The responsibility of a controller is just to execute an update method on a view, and the the view will do the rest.

There is one more thing…

Game is usually not only about updating a view based on a model but what we also want to do is to play the music and sound effects. Since a controller is responsible for handling user interaction it knows the best when to play a music or sound. But this is not always the case. If the player falls down on a platform a controller doesn’t know about it because this is a part of a game logic which stays in model. Can we then play sounds from the model? Argh… noo, we shouldn’t do it because we would break a SoC principle. How then we should do it? I will keep it for my my next post but I bet you already have got pretty nice ideas, don’t you?

Be Sociable, Share!
This entry was posted in iPhone and tagged , , , , , , , , , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

7 Comments

  1. Jackson
    Posted October 24, 2010 at 4:54 am | Permalink

    Great article, it gives me an idea on how to implement MVC on cocos2d but I think it would be easier to follow if you post simple example of your implementation of the MVC design pattern. Will you be putting one up any time in the future? Cheers.

  2. Posted October 24, 2010 at 10:43 am | Permalink

    Thanks for your feedback. I actually planned to write a follow-up post with some code samples and some diagrams that would better explain what was covered in this “only text” blog post :) It’s a bit delayed but I believe I would be able to post it within a week.

  3. Posted June 8, 2011 at 4:26 pm | Permalink

    ” touches are handled by CCLayer class which in my approach is a view”

    Any class can handle touches, CCLayer just provides a default implementation. But you can add the necessary touch methods and protocol relatively easy by making use of the undocumented CCTouchDispatcher class. You register self with the touch dispatcher and later unregister it (eg in dealloc) and add the necessary protocol to the @interface and that’s it – your class will now receive ccTouch(es)Began etc. messages.

    • Posted June 9, 2011 at 7:41 pm | Permalink

      Good to know, thanks! I was looking for such possibility earlier but couldn’t find an obvious solution. Knowing there is an option for handling touches directly by controller simplifies this model much.

  4. prabhu
    Posted July 6, 2011 at 1:00 pm | Permalink

    nice articale..I was always obssessed wit simplyfying the things using mvc architecture..
    consider simple tile based game,where we come across 3 situations
    1>pixel value of tile of sprite
    2>index of an object that we store in array or datastructure
    3>to simplify above two i would prefer to map pixel to array index and vice versa using new coordinate system structure ie CGPoint{x,y}.
    This will help massively in implementing graph (node,edge) theory based algorithms..

  5. cewxel
    Posted February 6, 2012 at 12:32 am | Permalink

    This is a good article, but something puzzles me, you said :

    “How does your model take the view? You can either pass it from the controller when a view is created or you can create a game model as a singleton and access it using a static method”

    Hum, I don’t really know if that’s a good idea.. I think that the model does not know about the view, and the view does not know about the model. They musn’t communicate each other. The model has to be like a brain so it can be re-used later in other implementation. don’t you think so ?

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

      The model should be created by controller, not the view. See my latest posts about a bit differently approach to the same problem.

5 Trackbacks

  1. [...] last post about implementing MVC pattern in cocos2d was definitely lacking some code examples. I must admit – I was writing it on my PC [...]

  2. [...] How to implement MVC pattern in Cocos2D game – Part 1 How to implement MVC pattern in Cocos2D game – Part 2 [...]

  3. By Learn Cocos2d | Blog | on July 6, 2011 at 2:41 am

    [...] This is a great article by Bartek which teaches you how to implement MVC pattern in Cocos2d in your game. [...]

  4. [...] How to implement MVC in cocos2d game [...]

  5. [...] 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 [...]

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="">