字体文件的加载优化尝试

ttf字体文件比较大,打包后小游戏很容易超过4M。

目前想到的思路是将游戏打包后找到字体文件目录,将字体压缩成zip包。在游戏加载的时候解压字体zip包到微信的用户目录下。然后通过cc.loader.load加载解压出来的字体文件。

现在遇到的问题是cc.loader.load加载到的是ttf字体的原文件。要怎么样处理才能赋给cc.Label对象的font属性?


解决方法:

用cc.Label对象有个font属性,font属性是cc.TTFFont对象。加载了ttf字体后就只要创建一个cc.TTFFont对象,然后将这个对象赋值给cc.Label对象的font就行。

cc.loader.load({url:wx.env.USER_DATA_PATH + '/' + 'IPix.ttf', type: 'ttf'}, (err, ret)=>{
        let font = new cc.TTFFont();
        font.name = 'IPix';
        font._native = 'IPix.ttf';
        font.loaded = true;
        font._fontFamily = 'IPix';
        cc.log(font);

        let node = new cc.Node();
        let lbl = node.addComponent(cc.Label);
        lbl.font = font;
        lbl.string = '字体加载测试';
        node.parent = cc.director.getScene().children[0];
})

2赞

微信小游戏环境下完整加载字体压缩包的流程。
这下不用担心ttf字体太大了。

unzipTTF() {
    if(cc.sys.platform === cc.sys.WECHAT_GAME) {
        let self = this;
        let fs = wx.getFileSystemManager();
        fs.access({
            path: wx.env.USER_DATA_PATH + '/' + "IPix.ttf",
            success(res) {
                console.log('成功加载本地字体', res);
                self.loadIPixTTF();
            },
            fail(res) {
                console.log('本地没有字体');
                // let tmpFile = cc.loader.md5Pipe.transformURL(cc.url.raw('resources/Font/IPix.zip'));
                let tmpFile = cc.url.raw('resources/Font/IPix.zip'); // cc.loader.load会自动去提交md5后缀,所以不需要用cc.loader.md5Pipe.transformURL
                cc.loader.load({url: tmpFile, type: 'binary'}, (err: Error, buf: ArrayBuffer) => {
                    if(err) {
                        console.error('load IPix.zip error ', err);
                        return;
                    }
                    console.log('load IPix.zip success');
                    fs.writeFile({
                        filePath: `${wx.env.USER_DATA_PATH}/IPix.zip`,
                        data: buf,
                        success(res) {
                            console.log('write IPix.zip success', res);
                            fs.unzip({
                                zipFilePath: wx.env.USER_DATA_PATH + '/IPix.zip',
                                targetPath: wx.env.USER_DATA_PATH,
                                success(res) {
                                    console.log('成功解压字体zip包')
                                    self.loadIPixTTF();
                                },
                                fail(res) {
                                    console.log(res)
                                }
                            })
                        },
                        fail(res) {
                            console.log('write IPix.zip fail', res);
                        }
                    });
                });
            }
        });
    }
}

loadIPixTTF() {
    cc.loader.load({url : wx.env.USER_DATA_PATH + '/' + 'IPix.ttf'}, (err, ret)=>{
        let font = new cc.TTFFont();
        // font.isValid = true;
        font.name = 'IPix';
        font._native = 'IPix.ttf';
        font.loaded = true;
        font._fontFamily = 'IPix';
        font._objFlags = 0;

        // 引擎在初始化cc.Label时设置默认的字体
        let oldOnLoad = cc.Label.prototype.onLoad;
        cc.Label.prototype.onLoad = function() {
            this.font = font;
            oldOnLoad.call(this);
        }
    });
}
2赞

还可以手动剔除一些不用的字,只留常用字 4M的字体可以变成1M左右

压缩成zip后只有几百k。不需要剔除。
而且玩家聊天也不知道他会输入什么。

为什么我5M的字体压缩成zip后还有3.2M

那可能你的字体就只能压成这样。