字体工具之BMFont

字体工具之BMFont


前言

做游戏的时候,会用到很多文本,主要可分为:

  • 动态文本
  • 静态文本

静态文字 就简单一些,完全可以由美工来做张图片,又美观、又大方、又好、又不费我们啥事~

动态文字 就需要程序来控制,什么时候显示什么,比如 游戏中的金币、分数、时间等,这些需要变化的,这类文本使用BMFont来制作字体集合。



简介

主界面:

各菜单介绍

看这个主界面,左上角两个菜单项——选择 与 编辑;
左面一个个小方块格子是一些常见字符,选择你想要生成的字符,它们会高亮显示,最后导出的文件所包含的字符就是高亮显示的那些(当然,还有后面我们添加的一些);
右面那一行行的是 左面字符的归属,比如 拉丁文、希腊文 等等,当你左面选择高亮的时候,右面相应归属前面的选项也要勾选上,否则没有效果。

菜单项之选项

其中的字体设置

其中的导出选项

菜单项之编辑


创建字体库流程

  1. 选择一些你想用的字符:点击右面你所需要的 所属前面的方块(选中),然后在左面选择你需要用的,高亮显示。(这个步骤,可以用 编辑选项 来辅助一下)
  2. 在字体设置界面来设置一下关于字体的部分:比如要生成的字体是什么样的,字体大小,抗锯齿 等等
  3. 在导出设置界面来设置导出相关细节
  4. 导出


关于添加汉字

  1. 我们将我们想加入的汉子录入到一个txt中,存储这个txt为 UTF-8格式
  2. 打开BMFont,字体设置的 字体找个里面有中文的(微软雅黑啥的),字符编码设置为 Unicode
  3. 打开编辑菜单项,找到 Select chars from file,然后找到之前存汉字的txt文件,点击打开,就行了
  4. 可以在 字体设置 的 Visualize中预览一下,就可以看到我们在txt中写的汉字了
  5. 生成



应用

目标,显示时间,格式为 XX分-XX秒

流程:

  1. 在TXT中输入时间、分、秒;在BMFont中找到 数字、符号、英文。
  2. 方便起见,我什么都没设置,直接导出,生成 一个.fnt 和 一个.png文件,把这两个文件,放到cocos2d-x资源目录下的fonts文件夹下。
  3. 因为显示中文比较麻烦,所以,我采用的是类似于android的string.xml方式,先在fonts文件夹下建立一个 chinese.xml ,里面存储相应的 key 与 汉字。然后,在程序中通过Dictionary调用key,来把相应的汉字提取出来,再根据 fnt,查找位置,显示在屏幕中。

chinese.xml内容:

1
2
3
4
5
6
7
8
<dict>  
<key>TIME</key>
<string>时间</string>
<key>MIN</key>
<string></string>
<key>SEC</key>
<string></string>
</dict>

通过Dictionary获取Key值内容

1
2
3
4
5
Dictionary *strings = Dictionary::createWithContentsOfFile("fonts/chinese.xml");  
//读取键中的值 objectForKey根据key,获取对应的string
const char *tr_time = ((CCString*)strings->objectForKey("TIME"))->getCString();
const char *tr_min = ((CCString*)strings->objectForKey("MIN"))->getCString();
const char *tr_sec = ((CCString*)strings->objectForKey("SEC"))->getCString();
  1. 在Cocos2d-x中,有专门的标签——LabelBMFont,它的速度比LabelTTF快很多而且LabelBMFont中的每个字符宽度是可变的。
    LabelBMFont继承自 Node、LabelProtocol、BlendProtocol类,所以它不仅具有Node的基本特性还实现了LabelProtocol接口(就是setString方法和getString方法)。

创建LabelBMFont对象

1
2
3
4
auto timeHZ = LabelBMFont::create(tr_time+StringUtils::format(": %d",min)+tr_min+StringUtils::format("-%d",sec)+tr_sec,"fonts/fontDemo.fnt"); 
timeHZ->setTag(11);
timeHZ->setPosition(Vec2(visibleSize.width/2,visibleSize.height/2));
this->addChild(timeHZ);
  1. 设置更新函数,一秒更新一次,60秒进1分等细节
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
void BMFontDemo::clockRun(float ft)
{
if( sec >= 59 ) {
if( min >= 59 ) {
min = 0;
}
else
{
min++;
}
sec = 0;
}
else
{
sec++;
}


//利用CCDictionary来读取xml
Dictionary *strings = Dictionary::createWithContentsOfFile("fonts/chinese.xml");
//读取键中的值 objectForKey根据key,获取对应的string
const char *tr_time = ((CCString*)strings->objectForKey("TIME"))->getCString();
const char *tr_min = ((CCString*)strings->objectForKey("MIN"))->getCString();
const char *tr_sec = ((CCString*)strings->objectForKey("SEC"))->getCString();

auto label = (LabelBMFont*)this->getChildByTag(11);
label->setString( tr_time + StringUtils::format(": %d",min) + tr_min + StringUtils::format("-%d",sec) + tr_sec );
}
  1. 运行





参考资料