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