學習 Cocos2d-x 有一陣了,現在要做個小東西,第一步就遇到了文字展示的問題,於是想把可能遇到的問題統統整理一下。這一部分也不侷限於wp8,全平臺應該都是一個解決方案。
先在腦袋裡大致想了一下,大致也就分為兩個部分,第一部分是普通文字如何展示,第二部分是老大難的中文展示問題。
文字顯示控制元件
Cocos2d-x 中使用 Label 來展示文字,看 官方介紹 可以知道,一共有三種型別的Label ,分別是 CCLabelTTF 、CCLabelBMFont 、LabelAtlas ,下面逐個來介紹下:
CCLabelTTF
優勢:
1、可以調整任意大小,支援間距調整
2、不需要額外的編輯器
劣勢:
1、建立和更新很緩慢,因為每次修改都要重新貼圖
使用例項:
CCLabelTTF* pLabel = CCLabelTTF::create("Hello World", "Arial", 24);
//指定水平、垂直對齊
pLabel = CCLabelTTF::create("Hello World", "Arial", 24, CCSizeMake(200, 160), kCCTextAlignmentCenter, kCCVerticalTextAlignmentTop);
//換行.
CCLabelBMFont
BMFont 即 Bitmap Font ,使用點陣圖來表現字型,一般生成2個檔案,一個是字型 *.fnt 檔案,一個是圖片 png檔案。
建立過程可以參考 這篇文章
優勢:
1、建立和更新十分的快
2、字型可以更加的個性化~
劣勢:
1、 要依賴額外的工具來建立,比如 Windows 下可以用這個 BMFont
2、 調整尺寸的時候 顯示效果可能變差
使用例項:
CCLabelBMFont* pLable = CCLabelBMFont::create("中國", "fonts/bitmapFontChinese.fnt");
pLable->setPosition(ccp(size.width / 2, size.height /2));
//BMFont的每一個元素可以轉化為 CCSprite,單獨做特效處理
CCLabelBMFont *label = CCLabelBMFont::create("Bitmap Font Atlas", "fonts/bitmapFontTest.fnt");
addChild(label);
CCSprite* BChar = (CCSprite*) label->getChildByTag(0);
//更新值.
label1->setString(string);
CCLabelAtlas
優點:同CCLabelBMFont
缺點:字元是固定大小,如果不想要固定大小的,就要用CCLabelBMFont
這個應該是速度最快的了,可是已經不被推薦了,現在還出現只是為了向後相容。
使用例項:
//基本用法,引數都封裝在plist裡
addChild(label1, 0, kTagSprite1);
//另外一種初始化的方法,指定png,和單位的寬高.
CCLabelAtlas* label1 = CCLabelAtlas::create("123 Test", "fonts/tuffy_bold_italic-charmap.png", 48, 64, ' ');
//更新值.
CCLabelAtlas* label1 = (CCLabelAtlas*)getChildByTag(kTagSprite1);
label1->setString(string);
官方文件還提到了個 CharMapFile 的概念
CharMapFile 就是我們之前初始化 CCLabelAtlas 用到的圖片,它有幾個要求:
1、不能超過256個字元
2、單位的寬度就是字元的寬度,用畫素表示
3、單位的高度就是字元的高度,同樣用畫素表示
CCLabelFont 和 CCLabelAtlas 效率要高的原因是,他們會把所有的元素都放在一張紋理上,這樣,不管你建立多少個 Label 紋理還是一張,而 CCLabelTTF 不同,每個Label 都會單獨有個紋理,所以效能就會下降很多,而且要佔用更多的記憶體。
關於中文的顯示
雖然遊戲開發一般要面向國際,但是我們做東西要沒有中文支援只有英文版本那就是捨本逐末了。如果我們什麼處理都不做,直接在初始化Label的時候,輸入中文,會發現無法正常顯示,這是因為我們編碼的字符集是GB2312,cocos2d-x的字符集是UTF-8,因此如果想要正常顯示,我們可以採取如下幾種方式。
1、轉碼,這個最簡單,也最直接。
char* HelloWorld::G2U(const char* gb2312)
{
int len = MultiByteToWideChar(CP_ACP, 0, gb2312, -1, NULL, 0);
wchar_t* wstr = new wchar_t[len+1];
memset(wstr, 0, len+1);
MultiByteToWideChar(CP_ACP, 0, gb2312, -1, wstr, len);
len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
char* str = new char[len+1];
memset(str, 0, len+1);
WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, NULL, NULL);
if(wstr) delete[] wstr;
return str;
}
2、 採用xml的方式來讀取,它的好處是修改起來更方便一些,而且很容易做多語言適配,testCpp裡也有這個例子,程式碼如下。
BMFontUnicode::BMFontUnicode()
{
CCDictionary *strings = CCDictionary::createWithContentsOfFile("fonts/strings.xml");
const char *chinese = ((CCString*)strings->objectForKey("chinese1"))->m_sString.c_str();
const char *japanese = ((CCString*)strings->objectForKey("japanese"))->m_sString.c_str();
const char *russian = ((CCString*)strings->objectForKey("russian"))->m_sString.c_str();
const char *spanish = ((CCString*)strings->objectForKey("spanish"))->m_sString.c_str();
CCSize s = CCDirector::sharedDirector()->getWinSize();
CCLabelBMFont *label1 = CCLabelBMFont::create(spanish, "fonts/arial-unicode-26.fnt", 200, kCCTextAlignmentLeft);
addChild(label1);
label1->setPosition(ccp(s.width/2, s.height/5*4));
CCLabelBMFont *label2 = CCLabelBMFont::create(chinese, "fonts/arial-unicode-26.fnt");
addChild(label2);
label2->setPosition(ccp(s.width/2, s.height/5*3));
CCLabelBMFont *label3 = CCLabelBMFont::create(russian, "fonts/arial-26-en-ru.fnt");
addChild(label3);
label3->setPosition(ccp(s.width/2, s.height/5*2));
CCLabelBMFont *label4 = CCLabelBMFont::create(japanese, "fonts/arial-unicode-26.fnt");
addChild(label4);
label4->setPosition(ccp(s.width/2, s.height/5*1));}
xml 內容,當然也要儲存為 UTF-8格式的。
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>chinese1</key>
<string>美好的一天</string>
<key>japanese</key>
<string>良い一日を</string>
<key>russian</key>
<string>Хорошего дня</string>
<key>spanish</key>
<string>Buen día</string>
</dict></plist>
3、修改cpp檔案的編碼
預設的編碼是GB2312,這就是造成文字無法顯示的問題,如果在win32平臺下,改成 utf-8 編碼就可以了,但是wp8上卻不可以,不知道為什麼,需要特意的改成utf-8 without signature,
但是這是一種最快速也最不安全的方法, 有可能會出現莫名其妙的無法編譯通過,所以非常不建議。
好了,文字的部分基本也就這些了, 下一部分,應該考慮考慮如何做 多解析度 適配了。
參考文章:
http://blog.csdn.net/zhy_cheng/article/details/9736973
http://cocos2d-x.org/wiki/Text_Labels?project_id=cocos2d-x
歡迎有興趣的童鞋加入Cocos2d-x 開發群 qq: 264152376