解决Cocos2d-x中文乱码的三种方法
http://www.cnblogs.com/msxh/p/5588775.html 众所周知,Cocos2d-x是一款不错的开源引擎,但是在Cocos2d-x中直接使用中文是无法正确显示的。比如下面的情况:
解决这个问题常用的有三种方法:1.通过转换为UTF-8编码来显示。2.使用iconv库来解决。3。使用解析xml或者json文件来解决。这里推荐使用第三种方法来解决,因为比较简单方便,还能支持I18N国际化。下面我们来一一详细了解一下每种解决方案的具体实现: 一、通过转换为UTF-8编码的方式显示出来,建立一个方法用于转换中文到对应的UTF-8编码,具体代码如下: 1 char *HelloWorld::FontToUTF8(const char* font){ 2 int len = MultiByteToWideChar(CP_ACP,0,font,-1,NULL,128); line-height:1.5!important">0); 3 wchar_t *wstr = new wchar_t[len+1]; 4 memset(wstr,len+1); 5 MultiByteToWideChar(CP_ACP,128); line-height:1.5!important">1,wstr,len); 6 len = WideCharToMultiByte(CP_UTF8,128); line-height:1.5!important">0,NULL); 7 char *str = new char[len+ 8 memset(str,128); line-height:1.5!important"> 9 WideCharToMultiByte(CP_UTF8,str,len,128); line-height:1.5!important">10 if(wstr)delete[] wstr; 11 return str; 12 } 函数的使用方法如下: 1 auto label = Label::creat(HelloWorld::FontToUTF8("不如跳舞"),Arial",128); line-height:1.5!important">36); 2 label->setPosition(320,128); line-height:1.5!important">300); 3 this->addChild(label); 这种方法仅仅依靠代码实现而不不需要额外的设置,但是效果并不是很稳定,容易产生某些错误或者依然乱码,因此不推荐该方法。
二、使用iconv库来显示中文 首先在创建好的cocos2d-x项目中搜索包含了iconv的文件名,然后把文件iconv.h的路径引入,如: #include cocos2dexternalwin32-specificiconincludeiconv.h" 然后在项目中创建一个GBKToUTF8方法来实现编码的转换: int HelloWorld::GBKToUTF8(std::string &gbkStr,char* toCode,255); line-height:1.5!important">char* formCode){
2 iconv_t iconvH;
3 iconvH = iconv_open(formCode,toCode);
4 if(iconvH == 0){
5 return -1;
6 }
char* strChar = gbkStr.c_str();
8 char** pin = &strChar;
9 size_t strLength = gbkStr.length();
char *outbuf = (char*) malloc(strLength*4);
char *pBuff = outbuf;
12 memset(outbuf,strLength*13 size_t outLength = strLength*4;
14 if(-1 == iconv(iconvH,pin,&strLength,&outbuf,&outLength)){
15 iconv_close(iconvH);
16 17 }
18 gbkStr = pBuff;
19 iconv_close(iconvH);
20 return 0;
21 }
1 //在场景中加入中文标签 2 std::string hello = "; 3 GBKToUTF8(hello,0); line-height:1.5!important">gb2312utf-8"); 4 CCLabelTTF *label1 = CCLabelTTF::create(hello.c_str(),128); line-height:1.5!important">20); 5 label->setPosition(250); 6 不过Android平台上的Cocos2d-x并没有提供相应的库,这就需要开发者自行将iconv库引入到项目中,然后编译。 由于前两种方法都比较复杂而且不稳定,因此推荐使用第三种方法(读取xml文件或者json文件的方法显示中文)。 三、读取外部xml或者Json文件显示中文 1.xml方法 使用xml解析中文十分的简单,首先我们需要准备一个xml文件。如下所示: <dict>
2 key>string1</3 string>欢迎学习cocos2dx4 >string25 >使用XML显示中文6 >string37 >key与string标签中的内容是对应的>
8 >
在xml文件中,<key>和<string>两个标签要保持一一对应的关系。这样就可以通过对key标签中的内容索引到对应的中文内容,从而显示中文字符。 需要注意的是保存此xml文件的时候编码格式要使用UTF-8(可以使用notepad++或者sublimeText之类的软件完成)。 之后我们就可以解析xml文件来读取中文啦: 1 创建词典类实例,将xml文件加载到词典中
2 auto *chnStrings = Dictionary::createWithContentsOfFile(CHN_Strings.xml 3 通过xml文件中的key获取value
char *str1 = ((String*)chnStrings->objectForKey(string1"))->getCString();
5 创建一个标签显示出来
6 auto* label1 = Label::create(str1,128); line-height:1.5!important"> 7 label1->setPosition(270);
8 addChild(label1);
9
char *str2 = ((String*)chnStrings->objectForKey(string211 auto* label2 = Label::create(str2,128); line-height:1.5!important">12 label2->setPosition(180);
13 addChild(label2);
14
15 char *str3 = ((String*)chnStrings->objectForKey(string316 auto* label3 = Label::create(str3,128); line-height:1.5!important">17 label3->setPosition(90);
18 addChild(label3);
这样中文就可以正确的显示出来了。
2.Json方法 Json的方法和xml大同小异,而且更简单,首先我们同样准备一个json文件,命名为language.json:
{ "start":"开始游戏","setting":"设置","exitGame":"退出游戏","info":"马三小伙儿","restart":"重新开始","win":"游戏胜利","returnMenu":"返回主菜单","bgMusic":"背景音乐","effectMusic":"音效音量" } 然后我们使用Jsoncpp库来读取json文件,jsoncpp可以到这里去下载:https://sourceforge.net/projects/jsoncpp/。解压之后我们只需要保留其中的srclib_json和 includejson下的文件,并将其放在项目的Classessjson目录下。或者图省事可以直接下载我这个配置好的json目录(提取码:40bb)。最后把json库导入到我们的cocos2d-x项目中。如图: 为了方便使用和修改我们这里创建一个ReadJson类,这个类里面只有一个静态的std::string ReadJson::getString(std::string name)方法,用来读取json信息: 1 std::string ReadJson::getString(std::string name){
2 Json::Reader reader;
3 Json::Value root;
4
5 std::string data = FileUtils::getInstance()->getStringFromFile(language.json 6
if (reader.parse(data,root,255); line-height:1.5!important">false) == true)
8 {
9 return root[name].asCString();
10 }
11 }
一步步解释一下函数中的内容: Json::Reader这个类是用来解析json文件的; Json::Value 这个类代表了json的一段数据; FileUtils::getInstance()->getStringFromFile("language.json")这个函数用来加载一个json文件,其返回值是一个字符串; 调用reader(Json::Reader类型)的parse函数开始解析json文件,解析的结果会保存在root对象中(Json::Value类型),读取它的值很简单,就像普通的数组使用索引一样,比如root["id"]。然后还可以根据值的类型进行转换,例如:root["name"].asCString(); 我们直接在程序中直接调用这个类的静态函数就可以方便的读取json中的字段了。比如: 开始游戏按钮 2 auto start_button = Button::create(button.png3 start_button->setScale(2); 4 调用ReadJson的getString()方法 5 start_button->setTitleText(ReadJson::getString(start")); 6 start_button->setTitleFontName(微软雅黑7 start_button->setTitleFontSize(16); 8 start_button->setPosition(Vec2(visibleSize.width / 2,visibleSize.height*0.7)); 9 this->addChild(start_button); 这样中文也可以正常的显示出来了。 总结上面的三种方法,无疑是第三种方法最方便和稳定了。而且使用解析xml或者json还有另外的优势就可以很方便地支持国际化。在游戏中设置一个语言选择按钮,然后根据选项来决定加载哪个xml或者json文件,这样可以很方便的快捷的切换游戏语言。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- PostgreSQL SQL的性能调试方法2--数据库log分析
- c – 使用back_inserter()或inserter()提高std :: copy()的
- fastjson开发学习(二)---对返回的json进行解析
- 我可以聚合数据帧并在R中保留字符串变量吗?
- oracle数据库备份、增加可用磁盘、设置归档、增加表空间
- NSXMLParser 解析xml详解
- c# – 标准Dispose模式的代码编织助手?
- Ruby Gem Twitter – 证书验证失败(Twitter :: Error :: Cl
- 如何使Ruby AES-256-CBC和PHP MCRYPT_RIJNDAEL_128一起玩得
- flex的legend显示问题---就是右边上边的那个标签小图形