微信小遊戲protobuf.js快速解決辦法
阿新 • • 發佈:2019-01-05
protobufjs在微信小遊戲環境中執行出錯,一時讓不少人被此問題卡住,做為pbkiller的開發者,必須將些問題了解清楚,目前提供下面幾個方案:
一. 使用預編譯js
將proto檔案轉換為js檔案使用,此方法支援protobufjs5.x~6.x
二. protobufjs5.x 動態載入方案
let ProtoBuf = require('protobufjs'); ProtoBuf.Util.IS_NODE = cc.sys.isNative; ProtoBuf.loadProtoFile = function(filename, callback, builder) { if (callback && typeof callback === 'object') builder = callback, callback = null; else if (!callback || typeof callback !== 'function') callback = null; if (callback) return cc.loader.load(typeof filename === 'string' ? filename : filename["root"]+"/"+filename["file"], function(error, contents) { if (contents === null) { callback(Error("Failed to fetch file")); return; } try { callback(error, ProtoBuf.loadProto(contents, builder, filename)); } catch (e) { callback(e); } }); var contents = cc.loader.load(typeof filename === 'object' ? filename["root"]+"/"+filename["file"] : filename); return contents === null ? null : ProtoBuf.loadProto(contents, builder, filename); };
此方法是將ProtoBuf.Util.fetch函式替換成cc.loader.load函式。
2.非同步載入proto檔案
之後載入proto檔案需要使用非同步方式
//建立一個共用的builder物件let builder = ProtoBuf.newBuilder(); ... ProtoBuf.loadProtoFile(filePath, (error, builder) => { let pb = builder.build(packageName); let player = new pb.Player(); player.name = 'zzz'; player.id = 123; let data = player.toArrayBuffer(); let player2 = pb.Player.decode(data); this.log(player2); }, builder);
三、 protobufjs 6.x 動態載入方案
let protobuf = require(‘protobufjs’);
protobuf.util.fetch = cc.loader.load.bind(cc.loader);
protobufjs 6.x動態載入可以解決載入問題,但protobufjs 6.x使用了new Function() 函式動態生成程式碼,導致在例項化proto物件時微信會報錯,此方法暫時不可取。
微信不支援XMLHTTPRequest API,而Protobuf中正好使用了此API,關鍵思路是使用cc.loader代替XMLHTTPRequest。
同時需要注意,微信開發者工具的執行環境中,在使用cc.loader.load、cc.loader.loadRes等函式時會經常出現回撥不響應的情況(切換場景也不生效),需要全部關閉微信開發者工具,或清空快取,再通過Creator運行遊戲,有時可能會反覆操作多次才能生效。
歡迎關注「奎特爾星球」微信公眾號,來我們一起成長!