1. 程式人生 > >cocos2d-x 中新增顯示文字的三種方式 LabelTTF 、LabelBMFont 和 LabelAtlas

cocos2d-x 中新增顯示文字的三種方式 LabelTTF 、LabelBMFont 和 LabelAtlas

在 cocos2d-x 中有三個類可以在層或精靈中新增文字:

  • LabelTTF
  • LabelBMFont
  • LabelAtlas

LabelTTF 直接支援使用 TTF 字型檔,可以支援全部的中文,但是效率稍低。LabelBMFont 適合顯示特定的文字,通過預先將文字生成圖片,提高了效率,但是不能支援全部中文。如果使用的文字不多,組合多,但是文字的編碼是連續的,比如數字,或者英文字元,那麼 LabelAtlas 更加適合你。

LabelTTF

先說 LabelTTF , TTF(TrueType Font) 是一種字型檔規範,是 Apple 公司和 Microsoft 公司共同推出的字型檔案格式,隨著windows的流行,已經變成最常用的一種字型檔案表示方式。

在 Windows Phone 中使用的時候,我們需要把字型檔檔案儲存在 Resources\fonts 資料夾下面,保證 Cocos2d-x 能夠找到字型。下面我們考慮在程式中使用字型 Consolas 顯示一個字串。

在系統資料夾 C:\Windows\Fonts 中找到 Consolas 字型,選中之後,進行復制。

複製到我們 Resources\fonts 資料夾中。

特別說明:

在 Andiord 和 iOS 中,程式碼中通過字型的名稱,而不是字型檔案的名稱來使用字型。但是,在 Windows Phone 中,卻不使用真實的字型名稱,而是使用字型檔案的名稱來使用字型。

我們在前面複製過來的字型檔名稱實際上是 consola.ttf,為了在後面使用這種字型,你需要將字型檔案的名稱改為 consolas.ttf 。或者字型名稱使用 Consola 。

程式碼中可以如下使用字型來建立標籤。

LabelTTF *label = LabelTTF::create("exp:+1234567", "Consolas", 40);
label->setPosition(visibleSize.width / 2, visibleSize.height / 2);
addChild(label);

或者使用 TTFConfig ,好處是可以重複使用字型的配置資訊,不用每次都指定字型名稱和尺寸。

TTFConfig ttfConfig("fonts/Consolas.ttf", 24);
auto labelHello = Label::createWithTTF(ttfConfig, "Hello, TTFConfig");
labelHello->setPosition(visibleSize.width / 2, visibleSize.height / 2);
labelHello->setString("Reset String");
addChild(labelHello);

文字是如何顯示在 UI 上的呢?實際上 Label 需要從字型檔中抽取字形,通過字形建立圖片紋理,然後才能顯示出來。如果字型檔比較大,比如說中文字型檔,我們沒有使用字型檔中所有的文字,那麼一個幾 M 的字型檔檔案就很浪費空間了,每次的重新生成紋理就更加浪費資源。我們可以考慮不使用字型檔案,而直接準備好文字的圖片直接顯示在 UI 上。

LabelBMFont

LabelTTF 每次呼叫 setString (即改變文字)的時候,一個新的 OpenGL 紋理將會被建立.。這意味著setString 和建立一個新的標籤一樣慢。 所以,當你需要頻繁的更新它們的時候,儘可能的不用去使用標籤物件。 LabelAtlas 或者 LabelBMFont 可以幫助我們實現這種效果。

首先,我們使用一個工具來幫助我們從字型檔檔案中抽取字形,生成我們需要的圖片,這個工具稱為 Bitmap Font Generator,可以直接下載到。

現在有兩個版本,我們直接使用最新的 v1.14 beta 來處理。先安裝一下。

下面啟動起來

進行字型設定,我們使用微軟雅黑來支援一下中文。

在彈出的對話方塊中選擇微軟雅黑,進行具體的設定。

然後,開啟記事本,建立一個文字檔案,寫入你希望使用的文字,注意,在儲存的使用要選擇 Utf-8 格式。

然後,在 Bitmap font generator 的 Edit 選單中,通過 Select chars form file 來選擇你剛剛建立的文字檔案,成功之後,你會在 Bitmap font generator 中看到你使用的文字已經被選中了。

現在,可以匯出圖片了。

看匯出的對話方塊。

Padding,文字的內邊框,或者理解為文字的周邊留空要多大 做後期樣式時這個屬性很重要,需要預留空間來給描邊、發光等特效使用 比如我預計我的樣式要加一個2px的邊框,然後加一個右下角2px的投影效果,所以我設定了padding:2px 4px 4px 2px

BitDepth,必須32位,否則沒有透明層

Presets,字型初始化的預設的顏色通道設定,也就是說字型的初始顏色設定是什麼樣的,建議都用白色字,可以直接設定為White text with alpha,即白色字透明底。

Font descript,字型描述檔案,可以使用text或者xml 也就是fnt檔案格式

Textures,紋理圖片格式,果斷png。

最後,匯出圖片檔案。

終於可以使用一下了。

首先,在資源中建立一個 xml 格式的 plist 檔案,在其中定義我們希望顯示的字串。我們將這個檔案直接儲存在 Resources 的目錄之下,名為 string.xml.

複製程式碼
<?xml version="1.0" encoding="utf-8" ?>
<plist version="1.0">
  <dict>
    <key>name</key>
    <string>你好,Microsoft 雅黑</string>
  </dict>
</plist>
複製程式碼

將我們剛剛生成的兩個字型檔案也複製到這個目錄下。

CCDictionary *strings = CCDictionary::createWithContentsOfFile("string.xml");
const char *charchinese = ((CCString*)strings->objectForKey("name"))->getCString();
LabelBMFont *label = LabelBMFont::create(charchinese, "helloFont.fnt");
label->setPosition(visibleSize.width / 2, visibleSize.height / 2);
addChild(label);

執行程式,就可以看到我們輸出了,顯示同樣的文字,我們僅僅需要一張 3.43k 的圖片檔案就可以了。

如果無法使用,可以檢視一下ccConfig.h中的CC_FONT_LABEL_SUPPORT是否enable了。

CCLabelBMFont CCLabelBMFont 相當於每次改變只改變了圖片座標,而CCLabelTTF要重新渲染.這個類使用之前,需要新增好字型檔案,包括一個圖片檔案 (**.png) 和一個 字型座標檔案 (**.fnt)。 在 cocos2d-x的示例專案中有現成的,可以先拿過來練習一下,找的時候注意兩個檔案的 名稱是相同的,只是副檔名不同。

這個沒辦法指定字型的字號,但可以用 scale 屬性進行縮放來調整大小。就當它是sprite。

LabelAtlas 

如果你用cocos2d-x專案模板建立過專案,那麼你已經看過它的效果了,就是左下角顯示幀率的數字。 因為幀率一直在變,使用CCLabelTTF的話效率太低,因為只是數字所以也犯不上使用 CCLabelBMFont 載入那麼大的文字影象,所以使用這個比較合適。

比如說,我們準備顯示 0-9 十個數字,我們可以在一張圖片中製作好這十個數字。每個數字都有相同的寬度和高度。將它儲存在資源中。別忘了設定複製。

比較重要的是,這十個數字要按照 ASCII 順序排列,我們要設定第一個字元的 ASCII 編碼,這樣,Cocos2d-x 就可以直接計算出不同字元對應的圖形了。

CCLabelAtlas* diceCount=CCLabelAtlas::labelWithString("1:", "nums_font.png", 14, 21, '0');

第一個引數:顯示的內容:1x,你也許會奇怪為什麼是1x,因為使用的png圖必須是連續的,因為程式內部是議連續的scall碼識別的。9的後一位的”:“,所以先實現x就得用”:“代替。

第二個引數:圖片的名字

第三個引數:每一個數字的寬

第四個引數:每一個數字的高

每五個數字:開始字元

LabelAtlas* diceCount = CCLabelAtlas::create("100:", "nums_font.png", 14, 21, '0');
diceCount->setPosition(Point(visibleSize.width - 150, visibleSize.height / 2 - 50));
addChild(diceCount);

附錄:

轉載地址:https://www.cnblogs.com/haogj/p/3835258.html

他的另一片文章:

cocos2d-x 中,字型檔案需要儲存在 fonts 資料夾中,如果字型路徑中沒有 fonts/ 會自動新增上這個資料夾。

如果字型名稱沒有 .ttf 字尾,也會自動加上這個字尾。

複製程式碼
unsigned char* CCFreeTypeFont::loadFont(const char *pFontName, ssize_t *size) 
{
    std::string lowerCase(pFontName);
    std::string path(pFontName);

    for (unsigned int i = 0; i < lowerCase.length(); ++i)
    {
        lowerCase[i] = tolower(lowerCase[i]);
    }

    if (std::string::npos == lowerCase.find("fonts/"))
    {
        path = "fonts/";
        path += pFontName;
    }

    if (std::string::npos == lowerCase.find(".ttf"))
    {
        path += ".ttf";
    }

    std::string fullpath  = FileUtils::getInstance()->fullPathForFilename(path.c_str());
    return FileUtils::sharedFileUtils()->getFileData(fullpath.c_str(), "rb", size);
}
複製程式碼

string::npos 就是 -1, 表示沒有找到子串,find 方法用來查詢字型名稱中是否包含了 fonts.

轉載地址:http://www.cnblogs.com/haogj/p/3855370.html