使用Laya开发微信小游戏时无法使用位图字体解决方案
-前言-
依照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开发微信小游戏时无法使用位图字体解决方案相关推荐
- 新手入门:如何用Laya开发微信小游戏?
1.环境准备 1.1 LayaAirIDE 1.7.14版本才开始集成微信小游戏开发. 1.2 微信小游戏开发工具 微信小游戏开发工具是小游戏开发与测试的环境,由于LayaAir引擎的开发者完全可以使 ...
- laya开发微信小游戏《奇异水族馆》之 观察者模式应用
初学laya开发的微信小游戏终于上线啦!!! 过年耗费3个月空闲时间开发出来的小游戏,游戏内容是模仿小时候玩过的一款pc端游戏叫怪怪水族馆~~ 微信搜<奇异水族馆>即可畅玩哦!! 暂时采用 ...
- Unity3d C# 开发微信小游戏分享图片、朋友圈等功能实现(含源码)
广告 通过一段时间的基于minigame-unity-webgl-transform插件的开发,算是稍微完整的一小个游戏已经制作完成,具体大家可以扫码体验一下: 感谢支持!! 前言 之前编写了一篇u3 ...
- unity开发微信小游戏(5)- 微信好友排行榜
效果展示: 如果感觉文章有用的,也烦请大家多多支持(扫描上面二维码n(*≧▽≦*)n)!!❤❤❤ unity开发微信好友排行榜可以说是把我虐的体无完肤,但为了拿下这功能,硬壳了三天,把我所踩过的坑分享 ...
- 微信小游戏申请注册流程+开发微信小游戏类目需要具备条件
微信小游戏申请注册流程+开发微信小游戏类目需要具备条件 在这里先讲一下,小程序和小游戏前面的注册流程都是一样的,在注册完毕登录小程序后台后选择类目时需要注意一下,我下面讲解的是已经通过认证的服务号进行 ...
- webpack + typescript 开发微信小游戏实践
源码地址 微信小游戏版本技术选型使用typescript开发 但是微信小游戏原生不支持 typescript 开发,于是探索一下使用ts开发微信小游戏 1. 创建小游戏 使用测试号,创建一个使用官方示 ...
- Unity 开发微信小游戏初探
前言 最近因项目需要开始研究Unity开发微信小游戏相关的知识.期间遇到各种坑,网上查阅的资料基本类似,无法解决自己遇到的问题.特用本文记录下过程,方便其他人遇到同样的问题时能够参考. 开发环境 Un ...
- 如何使用egret开发微信小游戏(一)Hello World
如何使用egret开发微信小游戏(一)Hello World 微信小游戏上线以来,凭借微信海量的用户,取得了巨大的成功,从跳一跳到大家一起来滑水,从2d游戏到3d游戏,许多游戏开发者都赚的盆满钵满,我 ...
- Unity开发微信小游戏步骤
unity开发微信小游戏 https://gitcode.net/mirrors/wechat-miniprogram/minigame-unity-webgl-transform?utm_sourc ...
最新文章
- Exception loading sessions from persistent storage
- [原]巧用RenderTexture
- 并发的HashMap为什么会引起死循环?(转)
- 洛谷 P1318 积水面积
- 学习动态性能表(20)--v$waitstat
- VTK:相互作用之InteractorStyleUser
- 查看数据库 MySQL 的版本信息的命令语句
- 向量表示 运动抛物线_流动的美丽函数——抛物线浅谈
- OCR基于深度学习下的CNN字符识别
- postgreSQL 自动递增序号
- 计算机无法启动print,本地计算机无法启动print spooler服务,错误1069怎么处理
- ubuntu如何连接网络
- 中报行情 锁定四大板块8只高送转潜力股 2011-7-9
- 前端标注软件-pxcook像素大厨使用心得
- 国外最流行的Bootstrap后台管理模板
- NOIP2017提高成绩
- 多多情报通:拼多多数据分析工具在哪?
- 方法论:后台产品经理的前世今生(一)
- 【刷题】BZOJ 2959 长跑
- Python.exe - 无法找到入口/无法定位程序输入点...于动态链接库