昨天改寫cocos2d-x的例程,想在其基礎上加上一個計分系統。沒有分數實在讓人沒有玩下去的動力!
我在主場景上加上了一個CCLabelTTF,用於顯示分數。
但是意外的發現,當內容含有中文時,CCLabelTTF的顯示內容為亂碼。
無奈只好Google百度尋求答案,明白了這個問題的緣由。
因為cocos2d-x內部是以utf8處理文字的,而VS直接輸入時文字編碼為GBK,如果新增L標誌,則為Unicode編碼。
解決這個問題有三種辦法:
-
將原始碼檔案儲存為utf8編碼,不過由於編譯器的問題,這種方式會導致很多無法預測的問題
-
將字串用utf8編碼集中存到一檔案中,然後用程式碼讀取這些字串來使用,這種辦法還能很好的支援多語言版本
-
使用字串時,先將其轉換為utf8編碼
我最終使用了第三種方法,第一種撇開不說,第二種實現起來比較麻煩,第三種則要方便很多。
一般在windows上,我們使用API MultiByteToWideChar來進行各種編碼轉換。
不過這東西只能在Windows上用,在cocos2d-x上用就有點不合時宜的感覺,畢竟安卓上可沒這個API。
還好cocos2d-x考慮很周到,它自帶了一個iconv庫
只需要在專案附加依賴項里加入libiconv.lib,並且包含標頭檔案iconv/iconv.h即可使用。
我通過這個庫封裝了幾個編碼轉換的函式,程式碼如下
#include "Tool.h" int code_convert(const char *from_charset, const char *to_charset, const char *inbuf, size_t inlen, char *outbuf, size_t outlen) { iconv_t cd; const char *temp = inbuf; const char **pin = &temp; char **pout = &outbuf; memset(outbuf,0,outlen); cd = iconv_open(to_charset,from_charset); if(cd==0) return -1; if(iconv(cd,pin,&inlen,pout,&outlen)==-1) return -1; iconv_close(cd); return 0; } /*UTF8轉為GB2312*/ std::string u2a(const char *inbuf) { size_t inlen = strlen(inbuf); char * outbuf = new char[inlen * 2 + 2]; std::string strRet; if(code_convert("utf-8", "gb2312", inbuf, inlen, outbuf, inlen * 2 + 2) == 0) { strRet = outbuf; } delete [] outbuf; return strRet; } /*GB2312轉為UTF8*/ std::string a2u(const char *inbuf) { size_t inlen = strlen(inbuf); char * outbuf = new char[inlen * 2 + 2]; std::string strRet; if(code_convert("gb2312", "utf-8", inbuf, inlen, outbuf, inlen * 2 + 2) == 0) { strRet = outbuf; } delete [] outbuf; return strRet; }
然後在每次要使用中文前,用a2u函式將文字轉換為utf-8編碼,使用例程如下:
//重新整理分數顯示 char buff[1024]; sprintf_s(buff, 1024, "得分:%d", _Score); _pLabelScore->setString(a2u(buff).c_str());
至此,我們可以在cocos2d-x中正常顯示中文了!