作为一个开源的游戏引擎,Phaser最大的特点就是源码写得十分漂亮,读Phaser的代码就像读诗一样优美。不仅如此,Phaser还实现了不同模块之间的解耦,你可以编译出一个不包含物理引擎的Phaser,本文详细介绍Phaser的编译。
Phaser的源码在这里
截止到写本文的时候,Phaser源码分成了三部分,v2,这是Phaser2.x的版本,由官方维护,v2-community,这也是Phaser2.x的版本,但是由社区维护。Phaser官方的最新版本是2.6.2,而后面的更新,都是社区在维护的。v3,这是Phaser3.x版本,提供了很多新特性,也最大程度兼容2.x的版本,可能取名叫Laser。
我们这篇文章会告诉大家怎么编译v2版本,v2和v2-community都是通过grunt来管理的,编译的方法一致,而v3则使用了webpack。
其实编译的步骤非常简单,下面介绍一下:
1、 下载并安装nodejs
可以到官网下载最新版nodejs,然后安装,不会装的自行百度教程。在命令行输入node –v,能够打印出版本号则安装成功。
2、 安装grunt-cli
执行,npm install –g grunt-cli,安装完成后,能够运行grunt --version,显示版本号则安装成功。
3、 安装依赖
进入v2的目录,执行npm install,安装编译所需要的依赖。
4、 编译
在v2目录下运行grunt进行编译。编译完成后,dist目录下就有phaser.min.js文件了。
当然,这样的话,只是编译了一个官方的phaser,和我们直接下载的没有区别,那么怎么编译一个自己的Phaser呢?
有两种方法,第一种是修改源码,然后在运行grunt编译,这样出来的phaser.min.js就是我们自己的Phaser了,笔者曾经就这样编译出自己的Phaser,修复了2个Phaser的bug。第二种就是通过grunt的配置项来定制化Phaser了,这样编译出来的Phaser体积会小很多。
以v2为例,我们打开v2下的Gruntfile.js,可以看到它的配置,我们执行grunt实际上执行的是grunt build任务。
grunt.registerTask('default', ['build']);
而build任务实际上是去除了ninja和creature特性的。
grunt.registerTask('build', 'Compile all Phaser versions just to the temporary dist folder', function() {
grunt.option('exclude', 'ninja,creature');
grunt.option('filename', 'phaser');
grunt.option('sourcemap', true);
grunt.option('copy', false);
grunt.option('uglify', true);
grunt.task.run('custom');
});
那么phaser到底有多少模块呢?从源码中,我们也能知道答案
'intro': { 'description': 'Phaser UMD wrapper', 'optional': true, 'stub': false },
'phaser': { 'description': 'Phaser Globals', 'optional': false, 'stub': false },
'geom': { 'description': 'Geometry Classes', 'optional': false, 'stub': false },
'core': { 'description': 'Phaser Core', 'optional': false, 'stub': false },
'input': { 'description': 'Input Manager + Mouse and Touch Support', 'optional': false, 'stub': false },
'gamepad': { 'description': 'Gamepad Input', 'optional': true, 'stub': false },
'keyboard': { 'description': 'Keyboard Input', 'optional': true, 'stub': false },
'components': { 'description': 'Game Object Components', 'optional': false, 'stub': false },
'gameobjects': { 'description': 'Core Game Objects', 'optional': false, 'stub': false },
'bitmapdata': { 'description': 'BitmapData Game Object', 'optional': true, 'stub': false },
'graphics': { 'description': 'Graphics and PIXI Mask Support', 'optional': true, 'stub': false },
'rendertexture': { 'description': 'RenderTexture Game Object', 'optional': true, 'stub': false },
'text': { 'description': 'Text Game Object (inc. Web Font Support)', 'optional': true, 'stub': false },
'bitmaptext': { 'description': 'BitmapText Game Object', 'optional': true, 'stub': false },
'retrofont': { 'description': 'Retro Fonts Game Object', 'optional': true, 'stub': false },
'rope': { 'description': 'Rope and Strip Game Object', 'optional': true, 'stub': false },
'tilesprite': { 'description': 'Tile Sprite Game Object', 'optional': true, 'stub': true },
'system': { 'description': 'System Classes', 'optional': false, 'stub': false },
'math': { 'description': 'Math, QuadTree and RND', 'optional': false, 'stub': false },
'net': { 'description': 'Network Class', 'optional': true, 'stub': true },
'tweens': { 'description': 'Tween Manager', 'optional': true, 'stub': true },
'time': { 'description': 'Time and Clock Manager', 'optional': false, 'stub': false },
'animation': { 'description': 'Animation and Frame Manager', 'optional': false, 'stub': false },
'loader': { 'description': 'Loader and Cache', 'optional': false, 'stub': false },
'sound': { 'description': 'Sound Support (Web Audio and HTML Audio)', 'optional': true, 'stub': true },
'scale': { 'description': 'Scale and Full Screen Manager', 'optional': true, 'stub': true },
'debug': { 'description': 'Debug Class', 'optional': true, 'stub': true },
'dom': { 'description': 'DOM Utilities', 'optional': true, 'stub': true },
'utils': { 'description': 'Core Utilities', 'optional': false, 'stub': false },
'create': { 'description': 'Create Support', 'optional': true, 'stub': true },
'flexgrid': { 'description': 'Flex Grid and Flex Layer', 'optional': true, 'stub': false },
'color': { 'description': 'Color Functions', 'optional': true, 'stub': true },
'physics': { 'description': 'Physics Manager', 'optional': false, 'stub': false },
'arcade': { 'description': 'Arcade Physics', 'optional': true, 'stub': false },
'ninja': { 'description': 'Ninja Physics', 'optional': true, 'stub': false },
'p2': { 'description': 'P2 Physics', 'optional': true, 'stub': false },
'tilemaps': { 'description': 'Tilemap Support', 'optional': true, 'stub': false },
'particles': { 'description': 'Arcade Physics Particle System', 'optional': true, 'stub': true },
'weapon': { 'description': 'Arcade Physics Weapon Plugin', 'optional': true, 'stub': false },
'creature': { 'description': 'Creature Animation Tool Support', 'optional': true, 'stub': false },
'video': { 'description': 'Video Game Object', 'optional': true, 'stub': false },
'pixidefs': { 'description': 'Pixi defaults', 'optional': true, 'stub': false },
'outro': { 'description': 'Phaser UMD closure', 'optional': true, 'stub': false }
我们可以使用grunt minimum来编译phaser2.6.2的最小系统
Running "uglify:custom" (uglify) task
File dist/phaser-minimum.map created (source map).
File dist/phaser-minimum.min.js created: 1.64 MB → 372.61 kB
Running "copy:custom" (copy) task
Copied 3 files
Done, without errors.
我们看到,它只有372.61k