cocos creator2动态更改字体

JavaScript010

cocos creator2动态更改字体,第1张

场景,使用cocos Creator制作一个页面文字编辑器,可以动态的改变label的文字。 在网上搜索出来的解决方案,基本上是 这样的写法,是在js加载之前就会执行的,而且,字体文件的路径不容易写对,所以有一个笨办法,但是是好用的。在画布之外的地方,用户看不到的地方添加多个label,并且使用特殊字体。在触发某个操作的时候,直接将特殊字体的label的font赋值给我内容label的font。就实现了动态改变字体打包之后:打包后会打包到build文件中,所以可以放心发布和使用。

1.新建工程。

2.复制下面代码到工程里面去。

var textField = new cc.TextFieldTTF("<click here for input>",

TEXT_INPUT_FONT_NAME,

TEXT_INPUT_FONT_SIZE)

this.addChild(textField)

textField.x = winSize.width / 2

textField.y = winSize.height / 2

TEXT_INPUT_FONT_NAME --字体

TEXT_INPUT_FONT_SIZE ---字体

3.测试运行,OK。

拿 creator 制作了个排行榜页面,不到20个Item,一个Item里只有两个 Label :名称和关卡。

发现在微信小游戏中打开,会卡顿。 对页面的创建过程计时,发现主要耗时在创建 Label 上。遂来分析下 cocos creator 2.1 的文本渲染流程。

感叹下,能看到源码真是太好了~~

求教,厦门有什么好的游戏开发的交流渠道呀,群也大都死水一潭,现实中也找不到交流的同好和空间。感觉太封闭了

回归正题...

cocos creator 的文本渲染有两种:

其中采用系统字体的,应该也是归属于 ttf 中。

涉及到的文件有:

还有其他相关的文件也是跟文本渲染相关,但是本文聚焦在 2d 、 webgl 和 ttf 渲染上,其他的就略过。

Label组件作为属性的容器,并在属性变更时,调用 _updateRenderData

Label的 _assembler 的定义在 core/renderer/webgl/label/index.js 找到

根据类型,找到 _assembler 的实现在 core/renderer/webgl/label/2d/ttf.js 中

core/renderer/webgl/label/2d/ttf.js 继承了 core/renderer/utils/label/ttf.js

通过 _getAssemblerData 可知,所有的 Label 组件共享同一个 canvs 元素

updateRenderData 做实际的文本计算(字体、宽高、基线等),并绘制纹理。

_updateTexture 首先清空 canvas (注意,此canvas全局唯一,所有TTF Label共享的)

然后绘制描边,绘制文本,有需要的话,绘制下划线,最后调用 _texture.handleLoadedTexture 将 canvas 提交到 gpu 纹理上。

以上可知,每个 Label 的创建,都要经历清空重绘 canvas ,然后提交纹理的步骤。每个 Label 的纹理都是单独的,并没有重用。

当时在微信小游戏上测试,平均创建一个 Label 耗时约30ms,创建十几二十个 Label ,感知到明显的卡顿。 最终弃用ttf label,改用 bmfont label避开这个问题。感觉这里有优化的空间?

一直以来,好奇 cocos creator 的描边实现,自己一直往 shader 那边,什么纹理扩边,卷积啥的去想。

实际上:

在文件 core/renderer/utils/label/ttf.js 第255行: