讨论cocos2d-x字体绘制原理和应用方案
来源:互联网 发布:风花雪月歌词解析知乎 编辑:程序博客网 时间:2024/05/16 04:55
个人一直认为,文字绘制是cocos2d-x最薄弱的环节。对于愤怒的小鸟之类的游戏,cocos2d提供的文字绘制功能已足够使用。但是对于一个mmo来说,则完全不够。一个优秀的mmo客户端必然会对其有进行优化和再封装的操作。
cocos2d-x支持两种文字绘制方式(均支持中英文),一种是CCLabelTTF,一种是CCLabelBmpFont。
CCLabelTTF原理是调用系统api绘制字形纹理到一张CCImage上面,然后将其作为CCSprite进行渲染。好处是支持系统绘制文字不需要附加字体文件(当然,如果有需要也可以使用自定义字体文件,但是本质还是系统api进行文字绘制。),文字排版和渲染效果相对较好(尤其是ios这种以文字渲染见长的系统)。 缺点是绘制文字速度慢,只要是文字绘制就会生成一张贴图,没有缓存机制。 没有提供获取字形矩阵的接口,上层无法进行再次排版(这就意味着上层无法做缓存机制,另外富文本渲染的时候也需要这种接口,否则就需要以牺牲效率为代价了)。
CCLabelBmpFont原理是通过字形生成工具预先生成一个字体文件(fnt的字体配置和png的字形纹理),好处是速度快,不耗内存。缺点是支持文字数目有限,所以只支持固定文字的渲染,如控件文字、物品名称等,如果是玩家姓名、聊天栏这类输入内容不定的,还是需要使用CCLabelTTF。
文字渲染后续值得优化的有两个方向:
1、直接使用freetype,然后就是正常的游戏引擎的文字处理方式,支持缓存,速度快,描边之类的效果也可以内嵌
2、从底层获取字形矩阵的接口,然后上层字行排版,这个可以兼容现有的代码,而且排版难度比我们想象中要低很多。
总结下,游戏固有内容的文字渲染推荐使用CCLabelBmpFont,输入内容不定的,选用CCLabelTTF
CCLabelBmpFont只支持一张png字形纹理图片(BatchNode绘制时需要保证贴图在一样纹理上面),但是很多bitmap font生成工具会生成多张png图片资源。我写了个python脚本用于合并多个png字形资源。
[python]import re, Image; def create(font): fp = open(font+".fnt", "r"); data = []; files = []; for line in fp: if line.find("pages=2") != -1: line = line.replace("pages=2", "pages=1"); elif line.find("file=") != -1: match = re.search("file=\"(?P<file>.+)\"", line); if match: files.append(match.group("file")); if line.find("id=0") == -1: continue; line = re.sub("file=\".+\"", "file=\"{0}\"".format(font +"_1.png"), line) elif line.find("page=1") != -1: match = re.search("y=(?P<y>[0-9]+)", line); y = int(match.group("y")); y += 512; line = re.sub("y=[0-9]+", "y={0}".format(y), line); data.append(line); fp = open(font + "_1.fnt", "w"); fp.writelines(data); fp.close(); height = 0; merge = Image.new("RGBA", (512, len(files) * 512), 0); for file in files: img1 = Image.open(file); merge.paste(img1, (0, height)); height += img1.size[1]; merge.save(font + "_1.png", quality=70); create("name_outline"); import re, Image;def create(font): fp = open(font+".fnt", "r"); data = []; files = []; for line in fp: if line.find("pages=2") != -1: line = line.replace("pages=2", "pages=1"); elif line.find("file=") != -1: match = re.search("file=\"(?P<file>.+)\"", line); if match: files.append(match.group("file")); if line.find("id=0") == -1: continue; line = re.sub("file=\".+\"", "file=\"{0}\"".format(font +"_1.png"), line) elif line.find("page=1") != -1: match = re.search("y=(?P<y>[0-9]+)", line); y = int(match.group("y")); y += 512; line = re.sub("y=[0-9]+", "y={0}".format(y), line); data.append(line); fp = open(font + "_1.fnt", "w"); fp.writelines(data); fp.close(); height = 0; merge = Image.new("RGBA", (512, len(files) * 512), 0); for file in files: img1 = Image.open(file); merge.paste(img1, (0, height)); height += img1.size[1]; merge.save(font + "_1.png", quality=70);create("name_outline");
- 讨论cocos2d-x字体绘制原理和应用方案
- 讨论cocos2d-x字体绘制原理和应用方案
- 讨论cocos2d-x字体绘制原理和应用方案
- 讨论cocos2d-x字体绘制原理和应用方案
- 讨论cocos2d-x字体绘制原理和应用方案
- 浅解cocos2d-x中的CCSprite绘制原理
- cocos2d-x 中文显示和自定义字体
- 【Cocos2d-x】中文和自定义字体
- cocos2d-x---ttf字体 和 fnt字体 的显示
- Cocos2d-x屏幕适配之Sprite绘制原理
- Cocos2d-x屏幕适配之Sprite绘制原理
- Cocos2d-x屏幕适配之Sprite绘制原理
- Cocos2d-x屏幕适配之Sprite绘制原理
- Cocos2d-x屏幕适配之Sprite绘制原理
- Cocos2d-x--绘制图片
- Cocos2d-x 图形绘制
- Cocos2d-x 绘制图形
- Cocos2d-x 图形绘制
- cocos2D-x之音乐与音效
- JS实现的表单验证和强大的身份证
- php开发笔记9-重写,重载,继承
- 【每日最爱一句】2013.06.06
- HDU3345:War Chess(BFS+优先队列)
- 讨论cocos2d-x字体绘制原理和应用方案
- V4L2驱动的移植与应用
- ibatis
- 如何打开网页及Get/Post数据
- I don’t want to see another “using namespace xxx;” in a header file ever again
- UVa146 ID Codes (排列)
- 拆开数字 2=1+1 2=2;
- 11300 - Spreading the Wealth
- RobotFrameWork(十三)RobotFramework与loadrunner性能测试结合(基于Remote库)