看了一下,网上并没有在Cocos Creator1.8中使用官方的google protobuf的完整解决方案。
由于项目以前用的java写的的服务器,处理google protobuf2的逻辑已经写好,所以我研究了一下google protobuf在cocos的应用。
最新更新:之前没有确定protobufjs和google protobuf是否兼容(即同样的proto文件转化成的二进制是否一样)。现在证实是兼容的。所以完全可以用protobufjs的解决方案,没有必要用我这个。pbkiller也是完全可以的。 不过具体的api有些不同,另外我觉得google的byte操作更好一些。所以遇到问题不能用protobufjs的用我这个方法就可以了
Creator 版本:1.8
google protobuf版本: 3.5
粗略步骤:
1 下载官方的google protobuf组件
2 通过.proto文件生成js文件
3 修改源码
4 测试
1 下载官方的google protobuf组件
这一步之前建议先阅读https://github.com/google/protobuf里面的文档
尤其是js分类下的文档
这一步的目标就是要弄到两个东西:
proto文件的编译器
google-protobuf.js
proto文件的编译器是为了把你写的.proto文件变成.js文件
为了得到proto文件的编译器,可以从https://github.com/google/protobuf/releases下载最新的js编译器(注意看下载的包的名字,是protoc,不是protobuf,很容易下错,比如本人。。)
google-protobuf.js是一个runtime支持,用于提供一些方法。
为了得到google-protobuf.js,可以直接通过npm下载安装,安装npm的方法请百度。
安装好npm后,在一个合适的文件夹内打开命令行,输入 npm install google-protobuf 安装google protobuf的runtime支持。
安装好后会出现很多文件,只有里面的google-protobuf.js是必须的,其他的可以删掉。
2 通过.proto文件生成js文件
首先要准备好proto文件,写proto的文件的语法用3或者2版本的都可以。
在有protoc.exe的文件夹打开命令行(或者打开命令行后cd 到那里去),
输入 protoc --js_out=import_style=commonjs,binary:. XXXXX.proto
其中 XXXXX.proto 是你的proto文件名,可以有多个空格隔开
结束后本文件夹内会出现一个新的js文件。
(看官方文档的朋友会注意到官网写了这里有两种生成方法:CommonJS和Closure,我选用了CommonJS,Closure应该也可以但是后面改源码的方式不同)
3 修改源码
首先把上面步骤生成的两个文件放在你的项目里。
cocos creator会提示是否导入为插件,选择否
然后会等待cocos编译一段时间,由于脚本代码多最多可能有几十秒
然后可以运行一下,肯定会报错。
首先是一个无法从undefined获得navigator。
仔细看源码会发现其实是goog.global为undefined了
再仔细一看就会发现是$jscomp.getGlobal(a) 这个函数的问题。
把它改成
其中很长的那行是原代码的那行。
本质上其实就是强行让他等于window
然后找到这行,用搜索工具吧,大约在40~45行
var COMPILED = !0, goog = goog || {}; goog.global = this;
改成
var COMPILED = !0, goog = goog || {}; goog.global = $jscomp.getGlobal();
然后就是最后要加一些导出的东西,在最后加上这三行:
接着修改proto文件编译出的那个js文件,
在最前面,找到这两行:
var jspb = require(‘google-protobuf’);
var goog = jspb;
把它改成
var jspbcomp = require(‘google-protobuf’);
var COMPILED = jspbcomp.COMPILED;
var jspb = jspbcomp.jspb;
var goog = jspbcomp.goog;
保存文件。
等待cocos编译一下(严格说这不是编译,是生成temp里面的quick script)
然后应该就没有报错了
4 测试
比如说本项目的proto文件编译出来的js文件是Packet_pb.js
我的proto文件里面有个int类型的type属性,类似于
message Packet {
required int32 type = 1;
}
那么可以写一个cocos creator的组件,在里面写
var packet_pb = require(‘Packet_pb’);
console.log(packet_pb);
var message = new packet_pb.Packet();
console.log(message);
message.setType(12);
console.log(message.getType());
观察log信息,最后如果可以输出12,成功!
再试一下:
var b = message.serializeBinary();
console.log(b);
观察log信息:
转化成2进制成功!