-前言-

依照Laya官方提供的位图字体使用方案时,在本地是可以正常使用的。当发布到微信小游戏上就没法使用。经过查找是缺少解析xml的库。

-正文-

方案1:引入xml解析库

缺少什么我们就引入什么,我们引入官方提供的js库

//修改bin目录下game.js文件
if ((typeof swan !== 'undefined') && (typeof swanGlobal !== 'undefined')) {require("swan-game-adapter.js");require("libs/laya.bdmini.js");
} else if (typeof wx!=="undefined") {require("weapp-adapter.js");require("libs/laya.wxmini.js");
}
window.loadLib = require;
require("index.js");
//添加解析库
window.Parser = require("./js/dom_parser.js");

具体的解析库就执行去找了。本文不是着重讲解这个方案,这个方案有下面几个缺点:

  • Parser可能会遭到全局变量污染,导致无法调用到我们想要的函数。
  • 我们始终都是拉取xml文件再进行解析,在浏览器层面数据传输xml的效率并不如json
  • 为了解析xml我们会额外引入js文件,js文件需要被解析,增加了游戏进入时间。

因此我们可以将Laya源代码修改成使用json文件作为数据配置文件。

方案2 修改laya.core.js实现json文件作为fnt配置文件

1.xml到json的转换

生成fnt及png

前面的步骤我们还是保持不变,依旧使用Laya官方提供的方式,使用bmfont这个软件制作fnt位图字体文件。制作好后我们将.fnt(实际内容是xml)及.png文件放到laya/assets/font文件夹下。

转换.fnt文件到.json文件

首先这一步需要node环境及安装gulp,如果没有安装环境首先安装环境。这里默认安装了node环境。

//1.安装gulp
npm install gulp --save-dev
//2.安装转档所需依赖
npm install iconv-lite --save-dev
npm install xml-js

安装好gulp后我们在项目根目录新建一个gulpfile.js文件来写我们的转换代码。

const fs = require("fs");
const x2j = require("xml-js");
const path = require("path");
const iconv = require("iconv-lite");
function xml2json(cb) {let allPath = [];readAll("./laya/assets/font/", allPath);for (let i = 0; i < allPath.length; i++) {let srcPath = allPath[i];if (srcPath.indexOf(".fnt") != -1) {//xml配置中可能存在中文,因此利用iconv-lite转换为GBK在进行转档let xmlData = fs.readFileSync(srcPath, {encoding:"binary"});let buf = new Buffer(xmlData,'binary');xmlData = iconv.decode(buf,'GBK');let jsonData = x2j.xml2json(xmlData,{compact:true,ignoreDeclaration:true,ignoreCdata:true,ignoreDoctype:true,ignoreComment:true,nativeType:true})let destPath = srcPath.replace(".fnt",".json");fs.writeFileSync(destPath,jsonData,"utf-8");}}cb();
}/*** 读取指定路径下的所有文件路径并赋值到out中* @param {string} parentPath * @param {Array<string>} out */
function readAll(parentPath, out) {try {let files = fs.readdirSync(parentPath);files.forEach(function (item) {let tempPath = path.join(parentPath, item);let stats = fs.statSync(tempPath);if (stats.isDirectory()) {readAll(tempPath, out);} else {out.push(tempPath);}});} catch (e) {console.warn("Path Error:" + e);return out;}
}
module.exports.xml2json = xml2json;

在gulpfile.js写好之后我们在终端直接执行gulp xml2json就可转档。我们上面使用的是xml-js这个库来实现的xml到json的转换,上面传给xml-js对象的参数不能变,否则后面解析json的代码也要做适当修改,不然是读取不到对应属性的。

2.修改laya.core.js

我们找到BitmapFont类,在loadFont方法下面添加一个loadFontByJson的方法。

//loadFontByJson
__proto.loadFontByJson=function(path,complete){this._path=path;this._complete=complete;this._isFntType = false;if (!path || path.indexOf(".json")===-1){console.warn('Bitmap font configuration information must be a ".json" file');return;}Laya.loader.load([{url:path,type:"json"},{url:path.replace(".json",".png"),type:/*laya.net.Loader.IMAGE*/"image"}],Handler.create(this,this._onLoaded));
}
/**
*@private
*/
__proto._onLoaded=function(){if(this._isFntType){this.parseFont(Loader.getRes(this._path),Loader.getRes(this._path.replace(".fnt",".png")));}else{this.parseFontByJson(Loader.getRes(this._path),Loader.getRes(this._path.replace(".json",".png")));}this._complete && this._complete.run();
}

加载完成后依旧回调到_onLoaded方法,通过_isFntType标志位来判断我们改BitmapFont实例是通过哪种方式加载的。接下来就创建parseFontByJson方法来解析数据即可。

/*** 通过json解析字体*/
__proto.parseFontByJson=function(jsonData,texture){if(jsonData==null || texture == null)return;this._texture=texture;var data = jsonData.font;var tX=0;var tScale=1;var tInfo = data.info._attributes;this.fontSize=parseInt(tInfo.size);var tPadding=tInfo.padding;var tPaddingArray=tPadding.split(",");this._padding=[parseInt(tPaddingArray[0]),parseInt(tPaddingArray[1]),parseInt(tPaddingArray[2]),parseInt(tPaddingArray[3])];var chars;chars=data.chars.char;var i=0;for (i=0;i < chars.length;i++){var tAttribute=chars[i]._attributes;var tId = tAttribute.id;var xOffset=parseInt(tAttribute.xoffset) / tScale;          var yOffset=parseInt(tAttribute.yoffset) / tScale;var xAdvance=parseInt(tAttribute.xadvance) / tScale;var region=new Rectangle();region.x=parseInt(tAttribute.x);region.y=parseInt(tAttribute.y);region.width=parseInt(tAttribute.width);region.height=parseInt(tAttribute.height);var tTexture=Texture.create((texture),region.x,region.y,region.width,region.height,xOffset,yOffset);this._maxWidth=Math.max(this._maxWidth,xAdvance+this.letterSpacing);this._fontCharDic[tId]=tTexture;this._fontWidthMap[tId]=xAdvance;}
}

修改完JS代码之后,我们需要在.d.ts中添加这个类的声明,不然Ts调用的时候编辑器会报错。
在LayaAir.d.ts文件中找到BitmapFont类声明,在下面添加方法接口

/*** 通过指定位图字体文件路径,加载位图字体文件,加载完成后会自动解析。* @param path json路径* @param complete 完成回调*/
loadFontByJson(path: string, complete: Handler): void;

至此我们所有需要修改的代码都修改完成了。外部调用直接调用loadFontByJson即可。

-结语-

在修改完下来,其实我们可以发现,Laya使用位图字体其实也是根据一张大纹理去索引uv去获取具体字的纹理数据。这跟图集实现基本是一样的,只是在外部调用设置Text会更加方便而已。
另外位图字体不能修改颜色(只能通过滤镜),改变字体大小(通过Scale修改大小)。追根溯源是因为这时候我们的字体已经不是渲染后的文字,是无法修改其属性,正常字体是拿着我们要修改的字体属性到Canvas绘图生成的,因此不能修改也是情有可原。因此想要使用位图字体的朋友们想清楚再使用。

任何一个小东西都蕴藏的无数的坑~~
原文链接:http://dengxuhui.cn/#html/blog/f02dea819604943226c8c7a247a8eb1a

使用Laya开发微信小游戏时无法使用位图字体解决方案相关推荐

  1. 新手入门:如何用Laya开发微信小游戏?

    1.环境准备 1.1 LayaAirIDE 1.7.14版本才开始集成微信小游戏开发. 1.2 微信小游戏开发工具 微信小游戏开发工具是小游戏开发与测试的环境,由于LayaAir引擎的开发者完全可以使 ...

  2. laya开发微信小游戏《奇异水族馆》之 观察者模式应用

    初学laya开发的微信小游戏终于上线啦!!! 过年耗费3个月空闲时间开发出来的小游戏,游戏内容是模仿小时候玩过的一款pc端游戏叫怪怪水族馆~~ 微信搜<奇异水族馆>即可畅玩哦!! 暂时采用 ...

  3. Unity3d C# 开发微信小游戏分享图片、朋友圈等功能实现(含源码)

    广告 通过一段时间的基于minigame-unity-webgl-transform插件的开发,算是稍微完整的一小个游戏已经制作完成,具体大家可以扫码体验一下: 感谢支持!! 前言 之前编写了一篇u3 ...

  4. unity开发微信小游戏(5)- 微信好友排行榜

    效果展示: 如果感觉文章有用的,也烦请大家多多支持(扫描上面二维码n(*≧▽≦*)n)!!❤❤❤ unity开发微信好友排行榜可以说是把我虐的体无完肤,但为了拿下这功能,硬壳了三天,把我所踩过的坑分享 ...

  5. 微信小游戏申请注册流程+开发微信小游戏类目需要具备条件

    微信小游戏申请注册流程+开发微信小游戏类目需要具备条件 在这里先讲一下,小程序和小游戏前面的注册流程都是一样的,在注册完毕登录小程序后台后选择类目时需要注意一下,我下面讲解的是已经通过认证的服务号进行 ...

  6. webpack + typescript 开发微信小游戏实践

    源码地址 微信小游戏版本技术选型使用typescript开发 但是微信小游戏原生不支持 typescript 开发,于是探索一下使用ts开发微信小游戏 1. 创建小游戏 使用测试号,创建一个使用官方示 ...

  7. Unity 开发微信小游戏初探

    前言 最近因项目需要开始研究Unity开发微信小游戏相关的知识.期间遇到各种坑,网上查阅的资料基本类似,无法解决自己遇到的问题.特用本文记录下过程,方便其他人遇到同样的问题时能够参考. 开发环境 Un ...

  8. 如何使用egret开发微信小游戏(一)Hello World

    如何使用egret开发微信小游戏(一)Hello World 微信小游戏上线以来,凭借微信海量的用户,取得了巨大的成功,从跳一跳到大家一起来滑水,从2d游戏到3d游戏,许多游戏开发者都赚的盆满钵满,我 ...

  9. Unity开发微信小游戏步骤

    unity开发微信小游戏 https://gitcode.net/mirrors/wechat-miniprogram/minigame-unity-webgl-transform?utm_sourc ...

最新文章

  1. Exception loading sessions from persistent storage
  2. [原]巧用RenderTexture
  3. 并发的HashMap为什么会引起死循环?(转)
  4. 洛谷 P1318 积水面积
  5. 学习动态性能表(20)--v$waitstat
  6. VTK:相互作用之InteractorStyleUser
  7. 查看数据库 MySQL 的版本信息的命令语句
  8. 向量表示 运动抛物线_流动的美丽函数——抛物线浅谈
  9. OCR基于深度学习下的CNN字符识别
  10. postgreSQL 自动递增序号
  11. 计算机无法启动print,本地计算机无法启动print spooler服务,错误1069怎么处理
  12. ubuntu如何连接网络
  13. 中报行情 锁定四大板块8只高送转潜力股 2011-7-9
  14. 前端标注软件-pxcook像素大厨使用心得
  15. 国外最流行的Bootstrap后台管理模板
  16. NOIP2017提高成绩
  17. 多多情报通:拼多多数据分析工具在哪?
  18. 方法论:后台产品经理的前世今生(一)
  19. 【刷题】BZOJ 2959 长跑
  20. Python.exe - 无法找到入口/无法定位程序输入点...于动态链接库

热门文章

  1. 关于工作站和台式机的区别介绍
  2. JS实现搜索匹配功能
  3. BigTable翻译
  4. 双目视觉学习——匹配综述及论文推荐
  5. 爆笑GIF:程序员的 40 个崩溃日常!
  6. 基于JAVA中学后勤设备保修维护管理系统计算机毕业设计源码+系统+数据库+lw文档+部署
  7. C语言编写猜数字游戏及随机数生成方法
  8. 冬季美白秘诀就是多吃对的东西
  9. 扬州考古工作人员考古现场被打 国家文物局:尽快查明
  10. libcad.so Crack,转换为多种文件格式