1、起因
学过了面向对象的编程,就不可避免的以对象的角度来思考程序结构。
牛皮少吹,说点实际的。
2.基类
首先,先来说一下cocos2d-x的程序类结构。
基本所有的元素都是CCNode的子类。比如CCSprite、CCMenu、CCLayer等。只是相应关注的功能点不一样。
我们通常需要的是一个复合的对象。
比如:塔防游戏。怪物头上都要有血条。这个东西是跟着怪物走的。显然应该在一个对象中。血条显示的是血量,这个数值自然是一个成员变量会比较好。但是如果我写成
Class MySprite : public CCSprite
{
......
}
会有问题。首先,血条与怪物明显是逻辑上的两个东西,另外,如果需要对其操作或向其中加入其它效果元素,事情将变得更难以管理。所以倒不妨直接采用基类CCNode:
Class MySprite : public CCNode
{
......
}
3、初始化
确定了基类,就可以开始着手写了。我可以添加一个CCSprite作怪物,一个CCControlSlider作它的血槽显示。这两个东西都用addChild加到MySprite中,此时可以把MySprite理解为一个CCLayer。所以这个类看起来应该是这样的:
Class MySprite:public CCNode
{
public:
CREATE_FUNC(MySprite);
virtual bool init();
}
然后在init中添加相应的功能就行了。
bool MySprite::init()
{
//add Sprite
.......
//add BloodBar
......
}
使用时 MySprite* sp = MySprite::create(); 这样的操作就可以创建一个新的复合对象了。
4、参数
一切都非常好,但是有点小瑕疵。现在想创建不同的怪兽,它们的血值是不一样的。能不能通过参数来进行配置呢?当然可以,这是我们自己的类,我们能控制一切。
在初始化时传入参数,是一个不错的选择。所以初始化函数调用应该是这个样子:
MySprite* sp = MySprite::create(100);
这样我就把怪物的血量100传进去了。好,就按这个思路写一个构造函数,写法就参照create好了。
先在.h文件中加入一个构造函数声明:
Class MySprite:public CCNode
{
public:
CREATE_FUNC(MySprite);
virtual bool init();
static MySprite* create(int hp);
protect:
int m_hp;
}
无参数的构造函数留不留看你需要了。如果你希望安全一些就彻底按照cocos2d-x的create方式来做,这也是推荐的写法。如果你觉得没必要的话只需在这个create中添加处理代码就行了。
更好的做法是在create中调用init,在init中添加处理:
Class MySprite:public CCNode
{
public:
CREATE_FUNC(MySprite);
virtual bool init();
static MySprite* create(int hp);
virtual bool initMySprite(int hp);
protect:
int m_hp;
}
其实现与CREATE_FUNC宏类似:
MySprite* MySprite::create( int hp )
{
MySprite*pRet = new MySprite();
if (pRet && pRet->initMySprite(hp))
{
pRet->autorelease();
return pRet;
}
else
{
delete pRet;
pRet = NULL;
return NULL;
}
}
bool MySprite::initMySprite(int hp)
{
//save hp
......
//add sprite
......
//add BloodBar
......
}
经过这些步骤,我们就可以通过参数来控制这个类的行为了。
5、总结
总结一下,如果想自己定制一个元素集合体,大体分以下步骤:
1、挑选基类。选择合适功能的基类,如果选择起来有难度,就选择CCNode。
2、编写默认初始化:create()。尽量使用create作为初始化函数,使编码风格保持一致。
3、编写特例初始化:create(...)。通过参数来控制类的行为。
本篇博客出自阿修罗道,转载请注明出处:http://blog.csdn.net/fansongy/article/details/9455307