很高興你來到我的博客,同時也要感謝你對cocos2d-x引擎的支持。不過,既然你在這個時候來到這里,那八成是因為你遇到了麻煩——在你的cocos2d-x應用中,中文的顯示似乎不太正常。
雖然cocos2d-x是一個跨平台的2D游戲引擎,但是目前我只使用VC在Win32平台下學習她。如果你是在其他平台上做開發,那么這篇文章對你可能沒有太大幫助,我建議你閱讀cocos2d-x的代碼,找出問題的關鍵,從而定制一個可行的解決方案。
作為一名初學者,你必定像我一樣跟着教程將代碼敲進編輯器里,保存,編譯,運行。卻驚奇地發現中文字符串要么不顯示了,要么顯示成了亂碼。心里想着,天啊,什么地方出問題了。然后打開百度、谷歌,搜索“cocos2d-x 中文”。於是你找到了解決方案,要把文件保存為“無簽名的UTF-8”編碼。
按照上面的方法操作,編譯,運行,這時你已經可以看到中文字符顯示正常了。如果你還有別的什么重要的事情要做,沒有時間聽我在這里廢話,那么你現在就可以點擊窗口上的叉叉離開了。
。。。。。。
咳咳。。。
你還在這里?你還想聽聽為什么會這樣嗎?
額。。。好吧,那我就簡單說一下。以創建一個label為例,當我們使用
CCLabelTTF * CCLabelTTF::labelWithString(const char *label, const char *fontName, float fontSize)
來創建label的時候,實際上這里的const char *參數期望的是UTF-8編碼的字符串(你可以查看CCImage_win32.cpp中BitmapDC的drawText函數來印證我的說法),如果傳入一個非UTF-8編碼的字符串,那么創建的label就會顯示得不太正常。
注意,這里所說的傳入參數的編碼是指程序運行時傳入的字符串的編碼,而不是源文件保存的編碼。這實際上是一個編譯器相關的問題,具體情況你可以通過這篇文章了解一下。http://blog.csdn.net/darkdong/article/details/6067119
簡單來說,如果你使用2005/2008/2010版的VC做開發,希望將UTF-8編碼的字符串硬編碼到源代碼中,並且不使用轉義字符"\xE6\xB1\x89"這種缺乏可讀性的方案,那么你必須將文件保存為“無簽名的UTF-8”編碼。
然而在VC上使用“無簽名的UTF-8”編碼保存代碼文件是有毒副作用的。有興趣的朋友可以跟我一起做個實驗。
新建一個“Win32 控制台應用程序”,然后添加如下代碼:
1 #include "stdafx.h"
2
3 int _tmain(int argc, _TCHAR* argv[])
4 {
5 const char str[] = "退出";
6 return 0;
7 }
然后將文件保存為“無簽名的UTF-8”編碼,編譯。
我用的是Microsoft Visual C++ 2010 學習版,輸出:
1>------ 已啟動全部重新生成: 項目: utf-8-test, 配置: Debug Win32 ------
1> stdafx.cpp
1> utf-8-test.cpp
1>d:\projects\utf-8-test\utf-8-test.cpp : warning C4819: 該文件包含不能在當前代碼頁(936)中表示的字符。請將該文件保存為 Unicode 格式以防止數據丟失
1>d:\projects\utf-8-test\utf-8-test.cpp(8): error C2001: 常量中有換行符
1>d:\projects\utf-8-test\utf-8-test.cpp(9): error C2143: 語法錯誤 : 缺少“;”(在“return”的前面)
========== 全部重新生成: 成功 0 個,失敗 1 個,跳過 0 個 ==========
有個叫wva的人遇到過類似問題,他向微軟提交了此bug
http://connect.microsoft.com/VisualStudio/feedback/details/341454/compile-error-with-source-file-containing-utf8-strings-in-cjk-system-locale
根據Visual C++ Compiler Team員工的解釋:
The compiler when faced with a source file that does not have a BOM the compiler reads ahead a certain distance into the file to see if it can detect any Unicode characters - it specifically looks for UTF-16 and UTF-16BE - if it doesn't find either then it assumes that it has MBCS. I suspect that in this case that in this case it falls back to MBCS and this is what is causing the problem.
看見了吧,對於那些沒有BOM的文件設計就是這樣的。從語氣上看,他們編譯器小組也不打算修改設計。所以呢,在VC上使用“無簽名的UTF-8”編碼的文件,你就是在抱着一顆不定時炸彈玩耍。因為你永遠都不敢確定哪些詞能通過編譯,哪些不能!
如果要硬編碼字符串,即便是字符編碼轉換也不一定能幫不上你。一旦你為此增加了字符編碼轉換的代碼,那么也意味着可移植性降低了。因為這從根本上是編譯器決定的。
所以如果你想要在你的cocos2d-x應用里使用中文,那么最好將它們存放到外部資源文件中去,然后提供一套文本資源獲取接口。
或者你僅僅是想像我一樣快點兒開始cocos2d-x引擎的學習,那么暫時放棄中文吧,應該能省下不少時間。
