前言
这是一次利用 Phaser
开发微信小游戏的尝试,并不能算作是教程,也像前一篇一样,还只能算是一篇笔记吧。(本文得到了 @大城小胖 的大力协助)
之前我们使用 three.js
进行了尝试,如果您错过了之前的文章,可以查看前文。
随着这几天的研究,有了一些新的进展,也尝试了一些新的引擎,发现问题还是蛮多的,不过官方的开发工具一直在更新,相信小游戏的开发环境会越来越完善的。所以建议大家等官方的开发工具和接口完备之后再进行正式开发,目前我们所做的都是一些尝鲜,并且不保证今后也能一定适用。
今天,我们要利用 Phaser
进行一次尝试。Phaser 是一款相当流行的免费开源 HTML 5 游戏框架擎,利用它可以轻松的开发 HTML 5 游戏。在国内也有很多开发者使用,详细的情况除了官网之外,也可以到 Phaser 中文网 站去了解(不过我这个网站应该是爱好者自建的,还是建议直接访问官方英文网站)。
准备工作
开始之前,我们需要准备如下资源:
- 最新版本的 Phaser CE(社区版)。其实目前最高的版本是即将正式发布的 Phaser 3,但是由于还在开发中,我们这里还是使用最新的 CE 版;
- 首先应该具有一定的 Phaser 开发经验,至少有所了解;
- 最新版本的“微信开发者工具”。
另外,我们还需要一个自定义的 weapp-adapter.js
,这是使用 wx API 模拟 BOM 和 DOM 的代码组成的库,我们在之前有过介绍(官方介绍),这里就不赘述了。我们会在文章后面的源代码中包含这个做了很多修改(来自 @大城小胖)的 Adapter,所以现在就认为它是基本正常工作的就可以了。
这一次我做了一个简单的示例,HTML 文件也放在源代码中,在页面上跑起来大概是这个样子:
项目结构
跟上一次不同,如果我们直接引入 phaser.min.js
到 main.js
里面:
import * as Phaser from 'libs/phaser.min.js'
会出现如下错误:
ReferenceError: PIXI is not defined
因为 Phaser 内置了 PIXI.js
作为渲染引擎,所以它需要 PIXI,因为是打包在一起的,所以我们之前的方法失效了。不过,Phaser 提供了自定义 Build 功能,所以我们可以根据自己的需要重新编译,移除一些不需要的功能比如微信小游戏开发根本不需要的手柄和键盘支持等等。这里有官方的详细文档。
很麻烦是吧?不过在 Phaser CE 的包里面其实有一个 build/custom
的文件夹,里面已经包含了分别编译好的文件,我们开发的时候必需的主要是三个文件:pixi.min.js
,p2.min.js
以及 phaser-split.min.js
我们将这三个文件拿出来单独使用即可。最后,我们项目的结构就是这样:
├── game.js ├── game.json ├── project.config.json ├── README.md ├── js | ├── main.js | └── libs | ├── gamelibs | | ├── p2.min.js | | ├── phase-split.min.js | | └── pixi.min.js | ├── symbol.js | └── weapp-adapter.js └── images ├── bg └── spritesheet
为了不让这篇笔记复杂化,我们粗暴的按照一定顺序将这个包引入,然后我们的 main.js
就是这样:
window.PIXI = require('libs/gamelibs/pixi.min.js') window.p2 = require('libs/gamelibs/p2.min.js') window.Phaser = require('libs/gamelibs/phaser-split.min.js') /** * 游戏主函数 */ export default class Main { /** * 构造 */ constructor() { console.log('Main') } }
运行一下,是可以跑的,我们应该已经成功的引入了 Phaser 必要的组件。
创建游戏对象
Phaser 的创建很简单,正常情况只要写这样一句就可以了:
var game = new Phaser.Game(320, 200, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update });
我们将我们的 main.js
的代码主体这样写:
/** * 游戏主函数 */ export default class Main { /** * 构造 */ constructor() { game = new Phaser.Game(320, 200, Phaser.AUTO, 'phaser-example', { preload: this.preload, create: this.create, update: this.update }); } preload() { console.log('载入素材') game.load.image('bg', 'images/bg/field_1920.png') } create() { console.log('创建内容') let back = game.add.image(0, 0, 'bg'); } update () { console.log('更新') } }
代码很简单:创建我们的游戏,然后载入一张图片,将其放到屏幕上。
跑一下,出现错误:
TypeError: window.scrollTo is not a function
window.scrollTo
显然是没有通过 Adapter 露出,看来创建游戏的时候,还将窗口滚动到顶部了。我们可以给它添加到 weapp-adapter.js
并露出。不过我们在微信小游戏中是不需要这个方法的,可以粗暴的加入:
window.scrollTo = function() {}
现在再跑,应该没有错误了,而且更新函数也一直在跑,但是屏幕上就是没有任何显示。
这是怎么回事?(黑人问号……)
因为:Phaser 自己会创建一个 Canvas 画布,而在微信小游戏中已经有了一个现成的 canvas
,随后再创建的 canvas
都是离屏的(off-screen),所以,游戏现在是跑在一个不可见的 canvas
里面。
所以,我们需要修改我们的初始化方法,让 Phaser 使用微信自动创建的 canvas
。
于是,将我们的游戏对象创建代码改成这样:
constructor() { // 配置参数 const conf = { width: size.w, height: size.h, canvas: canvas, renderer: Phaser.WEBGL, parent: 'phaser', transparent: false, antialias: false, state: { preload: this.preload, create: this.create, update: this.update }, scaleMode: Phaser.ScaleManager.EXACT_FIT }; // 创建游戏 game = new Phaser.Game(conf) }
再次运行,应该就出现画面了。
一些需要后面处理的问题
接下来我尝试了不少东西,包括 SpriteSheet 载入和处理、触摸事件响应等,看来制作一款游戏相对基本的功能都可以实现。
在提交的源代码中完成了:双手触摸屏幕的两边,角色会向该方向引动,在 iPhone X 上是这样,画面位置回头需要校正:
尝试通过 Phaser 自己播放音频的时候出现了问题,但是应该可以通过修改 Adapter 解决。而且可能通过微信提供的声音播放类也是能完成的,所以并没有努力尝试。
比较大的一个问题是在试图使用 Shader 的时候没有成功,这个目前看来好像是因为 getContext()
初始化参数的问题,那天大城小胖提交给微信团队的问题里面也有涉及,估计后面会得到解决。也可能是我哪里搞错了,后面会在小组中讨论。
结束语
好了,简单的介绍了一下怎么利用 Phaser
开发微信小游戏,这并不是一篇教程,只是在目前信息和资料不完善情况下的一种尝试,也希望大家一起参与到开发和研究中来,互相交流。
欢迎加入我们的小组:
微信小游戏小组
indienova 小组 参与源代码
为了方便大家参考,特提供源代码。其中包括一个微信小游戏项目和原始的 WebGL 项目,以及大城小胖修改过的 weapp-adapter.js
。
Github
源代码下载 代码其它相关链接
请先阅读:微信小游戏官方文档
目前,Cocos、Egret、Laya 已经完成了自身引擎及其工具对小游戏的适配和支持,访问对应的官方文档可以更快地接入小游戏的开发
老大开始写教程了啊
@dofy:好久不写了…
@eastecho:老当益壮啊 哈哈哈哈哈哈哈
大城小胖怒刷存在感啊....
不能跑filter/shader 可能是因为phaser在处理filter时 用到了 Stencil , 小游戏的webgl目前不支持Stencil.
@大城小胖:可是 PIXI.js 自己能跑
@eastecho:Stencil在pixi里主要用来实现 mask, 区域filter, 还有绘制几何图形(画线画圆那些)
如果你没用刀这些功能, 强制使用webgl是可以的.
phaser-ce 底层都用stencil做了什么我就不清楚了
Main直接由Phaser State管理比较好,感觉
3.x引入图片会提示createObjectURL不存在。如何解决这个问题?
@wonday:同遇
@wonday:我也遇到类似的问题了,解决了吗
atlas加载不了
老大game.add.text添加的文字在真机很虚怎么办