您的位置:首页 > 移动开发 > Cocos引擎

Cocos2d-x开发中遇到的问题汇总

2014-01-11 12:49 323 查看
学习Cocos2d-x有半年时间了,版本从2.1.3到3.0,对于这个引擎的感觉就是跨平台做的好,用起来简单,但是在开发的过程中难免还是遇到一些问题,这里做下汇总:

1、在Android系统上游戏崩溃,错误是由于内存访问越界

一般出现这种情况主要是由于Cocos2d-x中的对象大部分都是会自动进行内存管理,在Win32平台上可能不会出现什么问题,但是到了Android上面就会出现,要避免这个问题的出现就需要按照一些原则来使用Coco2d-x引擎中的对象

1、当某个Cocos2d-x的对象是属于类成员对象,那么在创建它的之后需要调用retain函数,以免出现所属类对象还存在,而该作为成员的对象却已经被自动回收了

2、当在某个函数中创建某个全局的Cocos2d-x引擎的对象时,也需要调用其retain函数,以免在函数退出后,对象被释放,之后对全局对象的访问出现崩溃。

3、Cocos2d-x框架中的Array类是非常容易被释放掉的,如果使用的Array对象要被作为参数传递,或被多次在不同函数中被使用,那么在创建这类Array对象也要调用它的retian 函数,以免程序崩溃。

2、关于Cocos2d-x多线程的替代方案的思考

在Cocos2d-x的主线程中调用的很多属于其框架下含有函数retian,autorealease等的调用的对象时是没有问题的,但是这些对象是不是线程安全的,因此就算输可以使用pthread这样跨平台的线程库也很不方便,不过有另外一种方法可以实现类线程的效果,那就是使用schedule函数对需要并行的逻辑进行定时调用,schedule的定时调用时线程安全的,因此可以利用该机制去实现想要的并行的逻辑。

3、3.0版本中编译项目出现 无法解析的外部符号 __imp__mci_Player之类的错误

我把2.x下的项目放到3.0下编译会出现这个错误,原因肯定是有的库没有引用进来,解决的办法是在链接器->输入->附加依赖项中加入winmm.lib

这里有一个关于版本移植的启示,在每次版本更新后如果出现缺少库或者链接阶段的错误时,不妨参考下目标版本引擎下的Sample

4、Cocos2d-x 3.0alpha中使用UserDefault 的setIntegerForKey() 导致程序崩溃

一般不会出现这类问题,由于UserDefault使用了tinyxml 进行xml文件的操作,出现这个问题的原因有可能是xml文件的路径中包含中文字符,这会导致tinyxml出错,因此开发Cocos2d-x项目

切记不要使用带中文的路径和文件名,以免出错。

5、在Sequence 和Spwan这2个Action中加入RepeatForever后没有执行,这个问题的主要原因还是出在Sequence和Spawn的实现代码中,但是有时候有需要这么做,是有解决办法的,下面的链接是鹏飞大牛给出的问题解释和解决方案:

/article/1384948.html

6、生成的Android apk真机下运行启动即出错 libc Fatal signal 11 (SIGSEGV) at 0x00000000 (code=1)

这个问题困扰了我很久,当时是我把3.0alpha版本下的一个项目移植到3.0版本下,新生成的apk报了这个错误,我以为是因为版本不同而导致的崩溃,各种修改C++代码,但错误一直在,后来我就把3.0版本自带的一个android项目的模板拷贝过来替换掉旧版本的android项目,奇迹出现了,生成的apk就没有这个错误了,我很奇怪,把3.0alpha的android项目内的文件和3.0版本的android项目内的文件做了一一对比,发现都是一样的,后来怀疑是不是依赖库还是旧的,于是把java层的和c++层的库都重新生成了下,结果旧项目还是报错,无法理解,找不出问题所在,不过问题总算解决了。

7、将一个Node从原父节点转而挂接到新的父节点的正确方法

直观的代码是这样的:

child->removeFromParent();

newParent->addChild(child);

但是执行到第二句就会报错,child已经被释放了,原因在于当执行第一句的时候,child从父节点的子节点列表中删除,会调用子节点的release函数将子节点的引用计数减1,

这时候就很可能出现引用计数为0的情况,而如果出现这种情况release函数内部会将该节点内存释放,也就是会执行delete this; 这时候child就变成指向非法空间了。

正确的代码是:

child->retain();

child->removeFromParent();

newParent->addChild(child);

先调用retain函数将child的引用加1,这样就不会出现child被意外释放的情况了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: