Cocos2d-X遊戲開發(五)

Cocos2d-X遊戲開發

  1. 文本

cocos2dx中有三個類可以添加文本信息:LabelTTF,LabelBMFont,LabelAtlas。

  1. Cocos2d-x中文亂碼:

不能顯示中文

createWithTTF(title, "fonts/Arial.ttf", 24)        

原因爲:字體不是中文字體

解決:將字體文件 simhei.ttf (黑體)拷貝到

資源文件夾的fonts文件夾中:

    //讀取菜單數據

    Dictionary *strings = Dictionary::createWithContentsOfFile("menu.xml");

    constchar *title = ((String*)strings->objectForKey("title"))->getCString();

    //添加一個文本

    autolabel = Label::createWithTTF(title, "fonts/simhei.ttf", 24 * 2);

    // 設定文本的位置

    label->setPosition(Vec2(origin.x + visibleSize.width / 2,

        origin.y + visibleSize.height - label->getContentSize().height));

    // 添加文本到圖層

    this->addChild(label, 1);

結果:

createWithSystemFont(title, "fonts/Arial.ttf", 24)    可以顯示中文

create(title, "Arial", 24)                            可以顯示中文

解決這個問題常用的有三種方法:

  1. 通過轉換爲UTF-8編碼來顯示。
  • 定義:

char *StartLayer::FontToUTF8(constchar* font) {

    int len = MultiByteToWideChar(CP_ACP, 0, font, -1, NULL, 0);

    wchar_t *wstr = newwchar_t[len + 1];

    memset(wstr, 0, len + 1);

    MultiByteToWideChar(CP_ACP, 0, font, -1, wstr, len);

    len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);

    char *str = newchar[len + 1];

    memset(str, 0, len + 1);

    WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, NULL, NULL);

    if (wstr)delete[] wstr;

    return str;

}

  • 使用:

LabelTTF *label = LabelTTF::create(StartLayer::FontToUTF8("新遊戲"), "Arial", 24 * 2);

這種方法僅僅依靠代碼實現而不不需要額外的設置,但是效果並不是很穩定,容易產生某些錯誤或者依然亂碼,因此不推薦該方法。

  1. 使用iconv庫來解決。
  • 定義

首先在創建好的cocos2d-x項目中搜索包含了iconv的文件名,然後把文件iconv.h的路徑引入:

#include"cocos2d\external\win32-specific\icon\include\iconv.h"

然後在項目中創建一個GBKToUTF8方法來實現編碼的轉換:

//編碼轉換,顯示中文

intStartLayer::GBKToUTF8(std::string &gbkStr, constchar* toCode, constchar* formCode) {

    iconv_t iconvH;

    iconvH = iconv_open(formCode, toCode);

    if (iconvH == 0) {

        return -1;

    }

    constchar* strChar = gbkStr.c_str();

    constchar** pin = &strChar;

    size_t strLength = gbkStr.length();

    char *outbuf = (char*)malloc(strLength * 4);

    char *pBuff = outbuf;

    memset(outbuf, 0, strLength * 4);

    size_t outLength = strLength * 4;

    if (-1 == iconv(iconvH, pin, &strLength, &outbuf, &outLength)) {

        iconv_close(iconvH);

        return -1;

    }

    gbkStr= pBuff;

    iconv_close(iconvH);

    return 0;

}

  • 使用:

std::string str = "新遊戲";

    GBKToUTF8(str, "gb2312", "utf-8");

    LabelTTF *label = LabelTTF::create(str.c_str(), "Arial", 24 * 2);

不過Android平臺上的Cocos2d-x並沒有提供相應的庫,這就需要開發者自行將iconv庫引入到項目中,然後編譯。

  1. 使用解析xml或者json文件來解決。
  • xml方法

<?xmlversion="1.0"encoding="utf-8"?>

<dict>

<key>menustart</key>

<string>新遊戲</string>

<key>menuclose</key>

<string>退出</string>

</dict>

在xml文件中,<key>和<string>兩個標籤要保持一一對應的關係。這樣就可以通過對key標籤中的內容索引到對應的中文內容,從而顯示中文字符。需要注意的是保存此xml文件的時候編碼格式要使用UTF-8。

    //創建詞典類實例,將xml文件加載到詞典中

    auto *chnStrings = Dictionary::createWithContentsOfFile("data.xml");

    //通過xml文件中的key獲取value

    constchar *str = ((String*)chnStrings->objectForKey("menustart"))->getCString();

    //創建文本

    LabelTTF *label = LabelTTF::create(str, "Arial", 24 * 2);

  • Json方法
  1. 同樣準備一個json文件,命名爲data.json

{

"start":"開始遊戲",

"setting":"設置",

"exitGame":"退出遊戲",

"info":"迅騰偉業",

"restart":"重新開始",

"win":"遊戲勝利",

"returnMenu":"返回主菜單",

"bgMusic":"背景音樂",

"effectMusic":"音效音量"

}

  1. 引入頭文件:

#include"cocos-ext.h"

#include"json/document.h"

  1. 頭文件中定義成員變量:

private:

    rapidjson::Document _doc;

    rapidjson::Value mDataArray;

    void initJsonData(floatdt);

  1. 讀取JSON數據:

    //讀取JSON

    std::string filePath = FileUtils::getInstance()->fullPathForFilename("data.json");

    std::string contentStr = FileUtils::getInstance()->getStringFromFile(filePath);

    log("%s", contentStr.c_str());

    //讀取數據到Document對象

    _doc.Parse<0>(contentStr.c_str());

    //讀取start節點值

    std::string str = _doc["start"].GetString();

  1. 結果:

 

  1. TTF類型標籤

LabelTTF類是通過TTF字體來實現的字體標籤。TTF格式是一種在計算機領域通用的字體格式,可以說是使用最爲廣泛的文字顯示格式。

    //讀取數據

    Dictionary *strings = Dictionary::createWithContentsOfFile("menu.xml");

    constchar *title = ((String*)strings->objectForKey("title"))->getCString();

    //添加一個文本

    autolabel = LabelTTF::create(title, "fonts/simhei.ttf", 24 * 2);

    // 設定文本的位置

    label->setPosition(Vec2(origin.x + visibleSize.width / 2,

        origin.y + visibleSize.height - label->getContentSize().height));

    // 添加文本到圖層

    this->addChild(label, 1);

LabelTTF類顯示靜態的標籤文本很方便,但是渲染速度相對較慢,並且缺乏靈活性。

  1. BMFont標籤

LabelBMFont來自於圖片文件,所以其實它的作用就相當於精靈表單,而其中的每一個字符則相當於精靈表單中的單個精靈對象。

    //讀取數據

    Dictionary *strings = Dictionary::createWithContentsOfFile("menu.xml");

    constchar *title = ((String*)strings->objectForKey("title"))->getCString();

    autolabel = LabelBMFont::create(title, "test.fnt");

    label->setPosition(Vec2(origin.x + visibleSize.width / 2,

        origin.y + visibleSize.height - label->getContentSize().height));

    //執行runAction動作,2秒後放大3倍

    label->runAction(ScaleBy::create(2.0f, 3.0f));

    this->addChild(label, 1);

LabelBMFont標籤提升了文字的繪製速度,所以,它是速度最快的字體類。

結果:

  1. Altas標籤

LabelAtlas是使用圖片作爲文字的一種方式,該類通過plist配置文件的描述來定義。

    //第一個參數:顯示的內容:1x,你也許會奇怪爲什麼是1x,因爲使用的png圖必須是連續的,

    //因爲程序內部建議連續的scall碼識別的。9的後一位的":",所以要實現x就得用":"代替。

    //第二個參數:圖片的名字

    //第三個參數:每一個數字的寬 與實際圖片寬相符合

    //第四個參數:每一個數字的高 與實際圖片高相符合

    //每五個參數:開始字符 左右方向

    //1:爲1x    ==== 6爲6 ==== :爲x

    LabelAtlas* label = LabelAtlas::create("1:", "nums_font.png", 14, 21, '0');

    label->setPosition(Point(visibleSize.width / 2, visibleSize.height / 2));

    this->addChild(label);

    LabelAtlas* label = LabelAtlas::create("3", "num.png", 120, 122, '0');

    label->setPosition(Point(visibleSize.width / 2, visibleSize.height / 2));

    this->addChild(label);

結果:

發佈了39 篇原創文章 · 獲贊 3 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章