cocos2d-x解決中文亂碼問題的幾種辦法

weixin_34219944發表於2014-03-17

昨天改寫cocos2d-x的例程,想在其基礎上加上一個計分系統。沒有分數實在讓人沒有玩下去的動力!

我在主場景上加上了一個CCLabelTTF,用於顯示分數。

但是意外的發現,當內容含有中文時,CCLabelTTF的顯示內容為亂碼。

 

無奈只好Google百度尋求答案,明白了這個問題的緣由。

因為cocos2d-x內部是以utf8處理文字的,而VS直接輸入時文字編碼為GBK,如果新增L標誌,則為Unicode編碼。

 

解決這個問題有三種辦法:

  1. 將原始碼檔案儲存為utf8編碼,不過由於編譯器的問題,這種方式會導致很多無法預測的問題

  2. 將字串用utf8編碼集中存到一檔案中,然後用程式碼讀取這些字串來使用,這種辦法還能很好的支援多語言版本

  3. 使用字串時,先將其轉換為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中正常顯示中文了!

 

相關文章