Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I read some articles on why I should separate game logic and UI code: That makes it possible to test game logic code can be independently of the rest. However, I am having trouble implementing this in cocos2d-x.

For example, the model usually depends on a Point coordinate and Sprite classes of the engine, which belong to the UI part. How can I separate them?

class Projectile : public Sprite{
public:
    CC_SYNTHESIZE(cocos2d::Point, _nextPosition, NextPosition);
    static Projectile initWithFile(const char* filename);

    Projectile(void);
    ~Projectile(void);
    virtual void setPosition(const cocos2d::Point & pos);
};    

I'm really confused how to test this object when I need to set its position in the unit test. How should I structure game code to be testable?

share|improve this question
add comment

2 Answers 2

up vote 2 down vote accepted
+50

ngoaho91 is basically hinting in the right direction but is not spelling it out explicitly, so I will try to make it more explicit.

So you took the framework and started implementing the logic within the separate framework classes. The problem why you can't simply test the game logic in isolation, is because it is not isolated.

You write that you Projectile is a Sprite, but that is simply not true. You use a sprite to visualize your projectile. The first thing is you need to separate your logic from your presentation, so like ngoaho91 said, without any presentation logic. You get bonus points if you wrap the logic into a separate library without any links to the presentation framework.

Then you build your presentation either by writing an observer called ProjectileView for each projectile or an observer that contains an array of Sprite objects, one for each projectile. For input you would write one object, say called PlayerController. This would then translate the raw inputs into calls on the game logic.

Now with this setup, you can take the game logic and put it through any amount of unit tests.

You may have noticed, I just decried MVC (model-view-controller). There is a valid reason why this pattern has persisted for such a long time, it separates the concerns in the system.


Before I finish, I want to give some real world advice. In general and especially the larger the code base becomes, it makes sense to factor your code into well defined chunks of responsibility. But with smaller project this just does not make that much sense, you can overdo it and thus the extra effort is not worth the cost. For example one common pattern is to clump the input handling into the Screen class instead of factoring it out into a separate object. My basic rule of thumb is, refactor when it starts hurting.

share|improve this answer
    
Thanks, basically I know MVC pattern, but I don't know how could put it through my game for unit tests. How about some math functions that cocos2d-x supported? How can I reuse it while I don't use framework classed for logic code? P/s:I want to separate logic and UI code for unit tests because I am being asked for doing this. –  R4j Apr 2 at 7:05
    
You have two options, either you use a third party math framework or you use just the math functions from cocos2d. The problem with such a framework that is clumps multiple bits together. You should be able to "only" use the logic bits in your model part and isolate it. –  rioki Apr 2 at 7:28
add comment

Implement your own Point class. That's good design if UI Point is seperate from logic Point.

//Point.h
class Point
{
public:
    int x,y;
};

Point different to cocos2d::Point. In Projectile class, you include and use it.

//Projectile.h
#include "Point.h"
class Projectile
{
public:
    char* image;
    Point* position;
};

Then render class, include the logic file.

//ProjectileRender.h
#include "Projectile.h"
class ProjectileRender: public cocos2d::Sprite
{
private:
    Projectile* logicMember;
public: 
    void Render()
    {
        cocos2d::render(logicMember->image,logicMember->position->x, logicMember->position->y);
    }
}

So Projectile is independence to any graphics component. If you need to render or something, call ProjectileRender, and send Projectile* to it to handle the logic section.

share|improve this answer
    
Point is just an example that I mentioned. There are many framework classes. If I create my own classes, how can I use the framework functions? I'm looking for an real world example that can separate game logic and UI code –  R4j Apr 1 at 7:04
    
what is framework function? are they graphics functions? in the logic section, you don't need graphics stuff. therefore, you probably don't need the whole class. i'm working on cocos2d too, and above are my solution. –  ngoaho91 Apr 1 at 7:19
    
I mean some math functions that cocos2d-x supported, like check contain point, transform... how can I use these functions without framework classes, write my own? –  R4j Apr 2 at 7:04
    
you can use kazmath which in cocos/math/kazmath to do math operation. and physics are at external/box2d. i usually not doing transform by using cocos2d animation effect. i done by my own, and cocos2d just get the result position. –  ngoaho91 Apr 3 at 1:36
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.