在 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);
附錄:
Unity3D BMFont使用圖片自定義字體(無需字體文件)