原创地址:http://blog.sina.com.cn/s/blog_923fdd9b0101e1l1.html
最近我们的cocos2d-x游戏项目已经进入了正式开发的阶段了,几个dev都辛苦码 代码。cocos2d-x还是一套比较方便的api的,什么action啊、director啊、ccpoint啊都蛮便捷的。但是我看到几个dev有时 候会很不知道用它们,还是首先自己去写函数……
用一些比较原始、低效率的方法……
甚至是copy / paste……
…………。
……。
这不科学啊!你不能这么勤劳啊!你这么勤劳要出事的啊!每年有多少程序员过劳死啊!程序员一定要是懒骨头才是正道啊!
首先第一个,看到有问题,要写很多代码处理问题,自己动手,丰衣足食——不是一 条好路,是一条革命的老路。我们前面有那么多前任程序员的尸体,要学会翻烂它们……然后本文也是菜笔写的,仅简整理一下自己用的比较多一些 cocos2d-x的util,帮助大家提高效率,要变懒,会偷懒,没有最懒,只有更懒。
1.数学类
cocos2d-x 里使用最多的数学类型是CCPoint,一个点,本质上也是一个向量,对于向量和向量之间有很多的数学操作要做,oh我知道要干什么,也许我知道怎么求一个值但是不知道怎么求得高效(或者不知道),怎么办我能偷懒吗?那当然可以。这其实并不是一个懒的标准,因为有一些方法写多了也可能确实稍微有那么点麻烦,所以自然cocos2d提供了一套ccp系列来帮助我们完成很多的工作,也显示一下库程序员照顾开发程序员的懒惰精神(当然他们自己也用,他们也很懒)。
那我们首先创建向量
ccp(x,y);//以坐标x,y创建一个向量这个大家都知道。ccpFromSize(s);以size s的width为x,height为y创建一个向量
有了ccp很多人就觉得自己已经够懒了,因为C++是可以用CCPoint()创建临时变量的,就是喜欢少打几个字吧。写个ccp(v1.x + v2.x,v1.y + v2.y)也不长……但是,有没有稍微再懒一点的?
——这个可以有。
基本的加法、减法、取负、数乘
ccpAdd(v1,v2);等价 ccp(v1.x+v2.x,v1.y+v2.y);ccpSub(v1,v2);等价 ccp(v1.x-v2.x,v1.y-v2.y);ccpNeg(v)等价 ccp(-v.x,-v.y); ccpMult(v,s);等价 ccp(v.x * s,v.y * s); s是个浮点数嘛
不错,但是这个写法不是那么符合我们原生C++程序员的习惯,向量运算符呢?可惜cocos2d原本是一套objc的API,没有操作符重载,cocos2d-x也没有像一些原生的C++数学库一样直接重载向量运算符。不过重载一下还是很方便的,我们的项目里声明了一个数学头文件,也就几行代码就好了:
代码" title="cocos2dx
inlinecocos2d::CCPointoperator+ (constcocos2d::CCPoint& v1,255)">constcocos2d::CCPoint v2) {returnccp(v1.x + v2.x,v1.y +v2.y); }inlinecocos2d::CCPointoperator- (returnccp(v1.x - v2.x,v1.y -constcocos2d::CCPoint&v) {returnccp(-v.x,-v.y); }operator* (floatscale) {returnccp(v1.x * scale,v1.y *scale); }floatscale,0)">v1) {operator/ (returnccp(v1.x / scale,v1.y /inlinebooloperator== (v2) {return(v1.x == v2.x) && (v1.y ==operator!= (return(v1.x != v2.x) || (v1.y !=v2.y); }
什么,你说还有 +=、 -=、 /=、 *= 没重载?哦,改那些必须得修改到cocos2d-x的源代码了,改完还得重新编译一遍,略微有点懒得改吧,至少CCPoint还是能用 = 赋值的。我们还是看看cocos2d-x还提供了什么数学方法吧。
取中点!本来也就一 ccpMult(ccpAdd(v1,v2),0.5f) 的事,开发者说不要,我就是要少打几个字,好吧库程序员就给了一个方法
点乘、叉乘、投影
喜闻乐见求长度、距离和各自的平方值(在仅需要比较两个长度大小时使用长度平方,因为省去了开方这一步,效率要高不少,这就不光是程序员的懒了,懒得要有效率)
当然数学不只有向量,还有一些其他的……这些也很经常用到。小懒一下。
2.语句宏
常用的,首先第一个,断言。
在这之后,也非常常用的,有遍历CCARRAY、CCDICTIONARY的宏。
CCArray*_array; CCObject* _object;用来遍历数组的临时变量CCARRAY_FOREACH(_array,_object)正向遍历{todo with _object....}CCARRAY_FOREACH_REVERSE(_array,_object)反向遍历} CCDictionary*_dict; CCDictElement* _elmt;遍历表的临时变量CCDICT_FOREACH(_dict,_elmt) {todo with elmt;}
在定义类型的时候,经常需要定义一些getter setter,有cocos2d从objc带来的CC_PROPERTY 和 CC_SYNTHESIZE。
1.CC_PROPERTY更适用于快速声明一个值属性,而CC_SYNTHESIZE更适用于声明一个对象。因为CC_SYNTHESIZE提供的默认set没有任何合法性检查对于值属性来说太不实用。
2.这些方法的声明全部都是virtual的,即便是内联,声明为virtual的方法也不会产生内联函数,所以不管是CC_PROPERTY还是CC_SYNTHESIZE,他们的效率都是不高的。
3.CC_PROPERTY的get方法都没有对函数体声明const修饰符,这意味着对const对象,并不能调用CC_PROPERTY声明的get方法(我怎么觉得这是个cocos2d-x的BUG……)。
4.在CC_SYNTHESIZE方法之后直接声明函数或者变量都会变成public:……注意,嗯。
不好用?跳过去看下定义,自己去定义一个呗……懒得看那就算了。
然后还有快捷的CREATE_FUNC,自动生成一个默认的静态create方法。这实在方便了
说到初始化,就不得不说到析构,还有一些析构相关的宏。我要release一堆对象,挨个都得判断对象是不是NULL?还要把release后的东西赋值NULL?程序员懒得写这么多行代码……
template<<span style="color: #0000ff;">typename t>voidswap<<span style="color: #0000ff;">typename t>(t& a,t& b);
好吧你赢了……
还有cocos2d库开发人员很喜欢用的CC_BREAK_IF,这个宏有什么特别的含义吗?难道其实不就是一行的 if(???) break; ?嗯,就是……没区别。但是你不觉得CC_BREAK_IF( ??? );懒地比人家高端吗?现在的IDE都能自动tab出宏耶!还有可以用下面的while(0)循环写还能代替一些if(???) return false;耶!