1、在VS下清空用户数据
CCUserDefault::purgeSharedUserDefault();
remove(CCUserDefault::sharedUserDefault()->getXMLFilePath().c_str());
有时候可能这两句话不管用,那就去路径cocos2d-2.0-x-2.0.4\Debug.win32下找UserDefault.xml文件,删掉即可。
用CCUserDefault来存数据时,CCUserDefault::sharedUserDefault()->setIntegerForKey("key",value);
key中不要包含特殊符号,否则可能,导致数据存储错误,使得其中部分数据无法读取到,此时可以查看UserDefault.xml文件中是否有错误数据。
struct cc_timeval now;
CCTime::gettimeofdayCocos2d(&now, NULL);
struct tm *tm;
tm = localtime(&now.tv_sec);
int year = tm->tm_year + 1900;
int month = tm->tm_mon + 1;
int day = tm->tm_mday;
int hour=tm->tm_hour;
int minute=tm->tm_min;
int second=tm->tm_sec;
但是copy到现在版本的Cocos2d-x平台下报错,不难看出是类型不匹配的错误,但是自己还是解决不了,在技术群里请教别人后得知,上面一段代码是以前版本下的代码,现在平台更新后,函数返回值类型变了,所以不匹配,请教后找到了改良后的方法:
//头文件
#include "time.h"
//struct cocos2d::cc_timeval now; // 秒/毫秒
//cocos2d::CCTime::gettimeofdayCocos2d(&now, NULL);
struct tm * tm;
time_t timep=time(NULL);
tm=localtime(&timep);
int year = tm->tm_year + 1900;
int month = tm->tm_mon + 1;
int day = tm->tm_mday;
获取当前时间(毫秒):
long getCurrentTime()
{
struct timeval tv;
gettimeofday(&tv,NULL);
return tv.tv_sec * 1000 + tv.tv_usec / 1000;
}
希望能帮到大家!
3、随机函数的随机种子
刚开始用的随机种子是:
srand(time(NULL));
发现每次运行的时候随机的数很接近,所以改成以下代码后成功:
//文件头加入此代码,不然报错
#pragma comment(lib, "winmm.lib ")
srand(timeGetTime());
第一个方法不能用估计是time(NULL)参数的问题,time(NULL)是一个固定值,所以以固定值为种子随机出来的数是不变的。但是在打包的过程中出现问题,因为安卓中可能不包含winmm.lib,所以说第二种我放弃了,虽然第一种我觉得有些不足,但是没办法最后还是用了第一种,多随机几次
4、使用CCSpriteFrameCache时需要注意的问题
使用CCSpriteFrameCache时,可把图片读入内存,如果读入了多个CCSpriteFrameCache,且图片中有同名的图片,则后者将不被读入内存,多个CCSpriteFrameCache公用的都是手机内存,如果两个图片名字完全相同,则被认为该文件已经存在就不会再次读入内存。所以应避免两个完全同名的图片同时被读入内存的情况。
5、Cocos2d-x中要提防局部变量
有一次我在Xcode中写了IAP 内付费的代码,调用计费时随便写了个局部变量buy:
InAppPurchases *buy= [[InAppPurchasesalloc]init:@"com.sharkmarine.yezi"];
去调用计费请求获取相关计费信息
- (void)getProductInfo
{
NSArray *product=[[NSArray alloc]initWithObjects:productId, nil];
NSSet * set = [NSSet setWithArray:product];
SKProductsRequest * request = [[SKProductsRequest alloc] initWithProductIdentifiers:set];
request.delegate = self;
[request start];
[product release];
}
与此相关的有个回调函数:- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
结果在未调用相关回调函数之前报错了:libobjc.A.dylib`objc_msgSend: EXC_BAD_ACCESS
后来搜了下原来是局部变量buy已被释放 ,所以当- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response函数收到信息后就会报错EXC_BAD_ACCESS。所以大家定义局部变量的时候要注意,不要出现像我这样的错误!
6、子弹拖尾部分代码
CCNode *ZiDanNode = newCCNode();
ZiDanNode->setPosition(CCPointZero);
addChild(ZiDanNode);
CCMotionStreak *im_streek =CCMotionStreak::create(0.1f ,10.0f , 2.0f ,ccBLUE ,"bullet.png") ;
im_streek->setScale(1.3f);
ZiDanNode->addChild(im_streek) ;
im_streek->runAction(CCSequence::create(CCMoveTo::create(0.6f,localposition),NULL)) ;
7、在.h中声明的Virtual类型的函数,要求必须在.cpp中实现
这类问题虽然在书中读到过,但在用到的时候还是不免会忘记,在此给大家提个醒吧~
例如在.h文件中声明以下函数:
virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent);
则要求在.cpp文件中实现函数,否则出现以下错误:
error LNK2001: 无法解析的外部符号 "public: virtual void __thiscall OnlineOrNot::ccTouchEnded(class cocos2d::CCTouch *,class cocos2d::CCEvent *)" (?ccTouchEnded@OnlineOrNot@@UAEXPAVCCTouch@cocos2d@@PAVCCEvent@3@@Z)
1>F:\cocos2d-2.1rc0-x-2.1.3\Debug.win32\Pokers_Online.win32.exe : fatal error LNK1120: 1 个无法解析的外部命令
遇到此类错误知道怎么回事就行!
8、字体创建的区别
CCLabelAtlas:
1、将字符串清空
2、将设置的字符串赋值给先前清空的字符串
CCLabelBMFont:
1、将字符串清空
2、将设置的字符串赋值给先前清空的字符串
3、将每个节点设置为隐藏(CCLabelBMFont 中对待每个字符是以CCNode的方式,因为他是CCSpriteBathNode的派生类)
4、显示新的字符(我们可以猜测这里的createFontChars的功能就是将新的字符赋值到每个节点中,后将节点显示出来)
CCLabelTTF
1、将字符串析构掉
2、重新new一个字符串
3、创建新的texture
4、将texture设置进去
从它们的setString函数调用开销可以看出一般我们在需要频繁改变显示的字符串的时候我们最好是采用CCLabelAtlas,比如说显示时钟的时候,其次是CCLabelBMFont,最后是CCLabelTTF