环境:windows7, VS2010, cocos2d-1.0.1-x-0.12.0, cygwin, eclipse, android sdk4.0.3, ndk r7b
在vs上开发,然后移植到android上.
20120718
CCArray的foreach操作:
cocos2d-x 本地通知调用的问题 CCNotificationCenter
在注册的postNotification消息函数中,不能再调用addObserver,可能会引发存储CCNotificationObserver对象的CCArray扩容,导致CCArray重新new了一块内存地址,CCArray首指针改变,当执行完返回postNotification函数的时候和原来的CCArray首指针不一致,导致内存读取出错。
observer->performSelector就是注册的消息回调函数。该函数内不能对再添加或减少自定义消息。
void CCNotificationCenter::postNotification(const char *name, CCObject *object) { CCObject* obj = NULL; CCARRAY_FOREACH(m_observers, obj) { CCNotificationObserver* observer = (CCNotificationObserver*) obj; if (!observer) continue; if (!strcmp(name,observer->getName())) observer->performSelector(object); } }
20120719
强制类型转换:
自定义类MainScene继承自CCLayer,使用手法同HelloWorld,MainScene::scene()直接new了一个scene对象,并将MainScene的对象挂到scene下。
但是后来调用的时候产生错误操作:MainScene* pScene = (MainScene*)(pDirector->getRunningScene());scene被强制转换成CCLayer,对所谓的MainScene对象成员操作,导致内存块异常,现象就是在莫名其妙的地方挂掉,每次都不同,内存块检测也报过异常。
危险的强制内存转换,切记切记!
20120723
最好不要写出全局变量初始化顺序有依赖关系的代码。
const CCSize WIN_SIZE = CCDirector::sharedDirector()->getWinSize();
一开始在VS上调试没事,移植到Android上,初始化的时候就挂了。
查了一下资料,原因是初始化顺序的问题。(具体初始化的顺序没搞清楚,⊙﹏⊙b汗,欢迎补充,感激不尽)
PS:找到了几篇初始化静态常量顺序的文章
1.控制全局变量初始化顺序 && #pragma详解
2.全局变量初始化顺序
int get_a() { static int a = 5; return a; } int get_b() { static int b = get_a(); return b; }
3.JAVA中初始化顺序复习
4.初始化有序常量的一点小技巧
20120726
playEffect
音效播放前要先preloadEffect,否则第一次播放音效没有声音。可以一次preloadEffect所有音效,android那边调用的是HashMap存储音效存放路径。
vs端不写preloadEffect也能正常播放,但是android端必须先preloadEffect才能正常播放,否则第一次播放没有声音。背景音乐没发现这个问题。
20120803
CCTargetedTouchDelegate 的继承 和 dynamic_cast
想写个可以响应touch的sprite
类定义成了这个样子:
class GemBoard : public CCSprite, CCTargetedTouchDelegate
CCTouchDispatcher::sharedDispatcher()->addTargetedDelegate(this, 0, true);
-addTargetedDelegate
-CCTargetedTouchHandler::handlerWithDelegate
-initWithDelegate
-CCTouchHandler::initWithDelegate
-dynamic_cast<CCObject*>(pDelegate)->retain();
-void CCObject::retain(void)
跟到这里,编译器告诉我CCObject的this指针是0,我晕呀。感觉太诡异了。
原因:CCTargetedTouchDelegate在上面的写法中是私有继承,而根据dynamic_cast的作用:(运算符可以在执行期决定真正的类型。如果downcast是安全的(也就说,如果基类指针或者引用确实指向一个派生类对象)这个运算符会传回适当转型过的指针。如果downcast不安全,这个运算符会传回空指针(也就是说,基类指针或者引用没有指向一个派生类对象)。)上面的情况就合情合理了。
今天学到了2个知识点:
1. class B: public A, C 这种情况下A是public继承,C是private继承;class B: A 这个A也是private继承
2.dynamic_cast 除了public 的其他都返回null
所以改成
class GemBoard : public CCSprite, public CCTargetedTouchDelegate
就正确了。发现自己的c++基础真烂。
20121101
今天不是万圣节吗,怎么变成了愚人节!!!
因为做的项目是VC++下开发,然后编成本地代码在Android上运行,所以有些地方需要上真机打印log调试。我日哦,我在代码里加了N多的log代码,就是一句也不打出来,在log上纠结了一天,一开始以为是cocos2d的代码出问题了,难道是自动屏蔽了log输出?上网查资料,当然什么也找不到。我就在加log代码,然后上真机,看不到log,然后继续加log代码,往复循环。下班的时候,同事看我这么纠结,就问我,vc上打断点看程序运行到log代码处了吗?结果是程序正常运行,断点根本不走,靠!原来我一直在一段废代码上加log!我的生命呀,就这样浪费了。我想起了一首神曲,有兴趣的同学可以听一下:Wrong hole - DJ Lubel
20121103
CCTexture2D::initWithData
bool CCTexture2D::initWithData(const void *data, CCTexture2DPixelFormat pixelFormat, unsigned int pixelsWide, unsigned int pixelsHigh,const CCSize& contentSize)
使用数据创建纹理,我试了无数遍,各种问题都考虑了,就是不知道为啥正常创建出来的纹理显示不出来。最后发现是contentSize这个最后的参数,我给的是(0,0)当然创建不出来了,一开始还以为是CCTexture2D创建成功后返回给我的生成的纹理大小。事实证明是我想多了……这个参数就是一开始指定要创建纹理的大小的。
20131220
runAction & OnEnter
今天学会了一个打开卷轴的动画
一开始自己想的办法是使用CCProgressTimer的CCProgressTo来执行这个动画,但是因为我做的不仅是单个sprite,还有挂在上面的Label,CCProgressTimer在绘制的时候不会处理它的子节点,后来想到一个办法,使用CCRenderTexture,将卷轴上的东西都画到上面,然后使用CCRenderTexture生成CCProgressTimer的sprite,效果达到要求。
但是CCRenderTexture向来是不推荐使用的,因为绘制效率低,而且游戏挂起后返回会丢失CCRenderTexture的资源。
找大能咨询,推荐使用CCClippingNode,设置它的Stencil,然后对这个Stencil做处理就能出展示的效果。
遇到个问题:我在addChild之后替换了Stencil,然后再用这个Stencil播放动画,死活播不出来,其他的都能播放动画。后来发现是在节点的OnEnter之后改变节点下的子,再针对这个子的所有事件都不会发生。因为子的OnEnter函数不会再执行了。
20130901
CCBatchNode vs ccBlendFunc
引擎版本:2.2.5
放在CCBatchNode下的骨骼动画设置不了ccBlendFunc,可查看CCArmature的draw函数,第一句就是判断batchnode是否为空,
想想也是,要是每个动画都有自己的ccBlendFunc,那就没必要放在batchnode下了。