Apologies in advance for the length of this post but I'm interested in how other people have solved some of the design issues around using Cocos2D (actually these are general game programming issues andnot specific to Cocos2D).
When you're designing your game, you end up with two parts to your basic game objects.
The first is the bit that gets displayed (call it the ViewObject), in Cocos terms this is a subclass of CocosNode and usually a Sprite. The second is the part that describes attributes and behaviours of your object, for example hit points, velocity, what they're carrying etc. call it the ModelObject
These objects have to be kept in synch somehow. I can think of three different ways of implementing this and I'm interested in which other people find easiest to use (or if there's a fourth fifth or sixth way!)
Inheritance
This approach means you make the ModelObject a subclass of the ViewObject. E.g. inherit from CocosNode (or Sprite or whatever).
You can add the ModelObject directly to a Layer and change its position, rotation etc. and let Cocos take cre of all the rendering.
Advantages:
This works very well when your world is limited to a single screen, it's simple and synchronisation is all taken care of for you because your ModelObject *is* your ViewObject
Disadvantages:
If you want to maintain separate coordinate systems for your world and screen it can cause a problem, for example using a physics system to determine collision response or mapping from isometric 3D world coordinates to flat 2D screen coordinates. You end up having a bunch of duplicate setPosition type methods, one to handle world coordinates and one for screen.
Also, if you have a large world you may not want to add 1000s of objects to your Layer when only 10 of them will be displayed (Layer doesn't seem to cull objects before rendering the screen).
Aggregation
In this approach, you have separate ModelObject and ViewObject classes. The ModelObject keeps a reference to the ViewObject. Now your main game code just calls methods on the ModelObject and it makes any necessary changes to the ViewObject. For example you can call
[ModelObject runToWorldCoordinate:worldCoord] and it will in turn call
[ViewObject playAnimation:run]
[ViewObject moveTo:screenCoord]
Advantages:
You can now cull objects by having the ModelObject remove the ViewObject form the Layer if it's not going to be rendered.
Disadvantages:
Now your ModelObject needs to know about the screen orientation and hold a reference to an AtlasSpriteManager (since it's responsible for creating the ViewObject) and also to the Layer (as it has to add and remove the sprite from the Layer).
MVC
In this approach, you still have ModelObject and ViewObject as different classes but introduce a third class, the Controller, which is responsible for synchronising updates between the two.
In this case you tell the Controller
[Controller moveObject:ModelObject toWorldCoordinate:worldCoord]
The Controller then calls something like
[ModelObject moveToWorldCoordinate:worldCoord]
if( [modelObject isOnScreen] )
[ViewObject renderAt:screenCoord];
Advantages
The model and view are completely separate and independent which is a nice design.
Disadvantages
More complexity as we have a new class to manage which is responsible for synchronising the state of the other two.
Having said that the last option is the most complex, it's also very common. Whenever you use Box2D you end up doing this, often Layer is the Controller, it updates the Box2D world and then uses the output to render sprites.
I'd love to hear which of these approaches people have had the most success with. Or whether it's simply horses for courses and a different approach depending on the game type.
Cheers
ScoobaDood