小游戏从0到1:第 2 课 创建第一个小游戏项目

目录

<code>了解运行机制 注册开发者帐号 安装开发工具 创建第一个项目 预览项目 自动预览项目 熟悉项目结构 如何调试代码 本课源码/<code>

文 / 石桥码农

本文约 11982 字符,阅读需要 17 分钟

微信小游戏是小程序的一个特殊分支,其执行环境和运行机制和小程序是一样的。

了解运行机制

微信在发布小程序之前,有一个佐助微信 Html5 页面开发的 WeixinJSSDK,地址是这个:

<code>//developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html /<code>

后来这个 SDK 几经发展,就演变成了小程序 / 小游戏底层的 WeixinJSBridge,如下所示:

WeixinJSBridge 可以看作是小程序 / 小游戏与微信 App 之间的一个桥梁。手机操作系统的本地存储、网络、罗盘、陀螺仪等硬件能力,小程序 / 小游戏都可以通过 WeixinJSBridge 访问。

在小程序 / 小游戏应用中,共有两个层次:

左边是视图层,负责视图的渲染。在小程序里主要渲染 WXML、WXSS、WXS 等这些内容;在小游戏里没有 WXML 组件,主要使用 Canvas 渲染视图。右边是逻辑层,负责 js 代码的执行。

不同的宿主环境对这两个层次的实现具有不同的方式:

在 iOS 手机上,视图层渲染是基于 iOS 的 WKWebView 实现的,逻辑层运行在 JavaScriptCore 中。在 Android 手机上,视图层渲染是微信基于 Mobile Chrome 内核自研的 XWeb 引擎渲染的,逻辑层代码则是运行在谷歌浏览器 V8 引擎中。V8 是一个由 Google 开发的开源 JavaScript 引擎,这个引擎在第 1 课中我们曾经提到过。在微信开发者工具中,视图层渲染是基于 Chromium Webview 实现的,逻辑层运行在 NW.js(//nwjs.io)中。Chromium 是 Google 谷歌浏览器背后的引擎,国内大多数双核浏览器都采用了 Chromium 内核。NW.js 原名 Node-Webkit,是一个基于 Chromium 和 Node.js 的应用运行时,通过它可以用 HTML 和 JS 编写原生应用程序。

这两个层次虽然在不同的平台上有不同的实现方式,但在所有平台上却具有相同的协作方式。

在逻辑层的 JS 代码中,像 setData 这样的方法想发挥作用,是通过 WeixinJSBridge 调用底层的 evaluateJavaScript 函数实现的;在视图层,如果有用户输入,例如单击了一个按钮,这个按钮上我们事先绑定过一个函数,那么这个函数也是通过 evaluateJavaScript 间接被调用的。

evaluateJavaScript 方法有一个问题,就是执行效率太低。在执行时,它是先将数据对象转换为字符串,再将字符串与 JS 代码拼接成一份脚本文本后再执行。往来调用都是这样的一种模式,重复且单调。两个模块是独立的,并不存在直接的调用渠道。具体可以看下面这个示例感受下:

<code>String js = "javascript:" + functionName + "('" + s + "')"; mWebview.evaluateJavascript (js, new ValueCallback() { @Override public void onReceiveValue (String value) { ... } }); /<code>

这是一段 Java 代码,是在 Android 应用中通过调用 webview 对象的 evaluateJavascript 方法,达到执行 js 代码的目的。第一行中 js 即是一段准备执行的代码文本。

两个层次单通道通讯,不能并发,往来都要文本与对象先转换一下,这是小游戏 / 小程序中产生性能瓶颈的最大祸首之一,在开发中尤其值得注意。在小程序开发中,JS 是主要的编程语言,但是微信又创造了一个 WXS 语言,用于在 WXML 中编写操作 DOM 元素的代码,并且还不能与逻辑层的代码进行直接的交互,其目的就是为了解决这个性能瓶颈。

但是对于初学者,在目前阶段了解这些运行机制就足够了,接下来我们开始创建并运行自己的第一个小游戏项目。

创建小游戏项目需要一个开发帐号,和一个微信开发者工具。我们先解决第一个问题。

注册开发者帐号

如果之前注册过小程序帐号,这个帐号能否直接用于小游戏开发呢?

这是不可以的,虽然说小游戏是小程序的一个特殊类目下的分支,但两者帐号是互斥独立的。并且一个邮箱只能注册一个帐号,如果用它注册过小程序帐号,注册小游戏帐号就不能再用了。

打开微信公众平台 mp.weixin.qq.com,选择第三个分类「小程序」,开始注册一个小游戏帐号。注册过程按提示即可完成。注册完成后登陆帐号,打开设置 -> 开发设置,记录下 AppID 备用。例如笔者的 AppID 是 wx2e4e259c69153e40,这个 AppID 在接下来创建项目时会用到。

有人问,能否用别人的 AppID 开发?

这是不可以的。微信开发者工具需要微信登陆,如果与小游戏绑定的微信不一致,会报 “登录用户不是该小程序的开发者” 错误。

注意:在注册小游戏帐号时,注意在选择服务类目时,一定要选择游戏类目。如果选择了非游戏类目,则该帐号只能用于小程序开发了。微信是以服务类目区分小程序和小游戏的。

有了小游戏帐号,接下来我们还需要安装一个微信开发者工具,它是微信开发的专用于开发小游戏 / 小程序项目的 IDE(集成开发环境),集成了项目开发需要的所有工具,包括代码管理都有包含。

安装开发工具

在小程序 / 小游戏上线之前,微信开发者工具就已经存在了,当时它只用于微信内 Html5 页面的开发调试。

在工具的选择上,除了微信官方提供的微信开发者工具,还有像 Egret Wing 等第三方集成开发环境,也可以根据需要自由选择。也有人使用 Webstorm、Vim、Sublime Text 3、VSCode 作为小游戏项目的开发工具。

但对于初学者来言,建议使用官方出品的工具。官方工具不仅可以开发项目,还附有项目发布、云开发管理、代码管理等内置工具,与微信提供的基础库版本最为契合,更新也最为及时。

如何下载呢,前往微信开发者工具下载页面:

<code>//developers.weixin.qq.com/minigame/dev/devtools/download.html /<code>

下载、解压并按照提示安装即可。

微信开发者工具是跨平台的,有三个版本:windows 64 版本、 windows 32 版本和 mac 版本。

开发者可根据自己的操作系统选择,苹果用户选择 mac 版本,大多数 windows 用户应该选择 windows64 版本,只有极少数 xp 用户和 windows7 用户选择 windows32 版本。

工欲善其事,必先利其器。在安装了微信开发者工具之后,为了方便开发,提升编码效率,最好对开发环境做一些简单配置。

打开微信开发者工具,选择菜单设置 -> 编辑设置,将文件保存下的除「修改文件时自动保存」之外的其它选项全部选中。这样在开发时,当修改文件时不需要频繁地手动保存文件,文件会自动保存;当需要预览变化时,直接单击「编译」按钮就可以了。

创建第一个项目

现在我们有了帐号和开发者工具,也配置好了环境,准备工作做完了,接下来我们基于项目模板,快速创建一个小游戏项目,并让这个项目运行起来,开始建立对小游戏开发的初步认识。

打开微信开发者工具,选择小程序项目 -> 小游戏 -> 新建项目,打开如下所示的项目创建面板:

项目名称随意,可以填写 “人生第一个小游戏项目” 或者其它名称。目录,选择一个空目录。AppID 填写先前在本课第二步记录下的 AppID。后端服务可以选择「不使用云服务」,或「小程序・云开发」都可以。云开发是一种后端开发技术,在后面课程中会有介绍。

当一个空目录作为目标目标被选用时,并且 AppID 是小游戏帐号的 AppID,此时点击「创建」,工具将自动基于模板创建一个小飞机游戏项目。

有人问,为什么我创建的不是小飞机项目?

这时候要检查一下 AppID 是否输入 —— 因为创建项目是可以不填写 AppID 而使用测试号的,以及输入的是不是小游戏的 AppID。如果不是 AppID 的问题,要检查一下目标目录是不是空目录。

如果没有注册小游戏帐号,也可以单击使用「测试号」,进入体验模式。通过体验模式创建的项目,一些功能诸如上传 / 预览等不能使用,一些开放接口诸如登陆、拉取用户信息等不能调用。

项目创建之后,如何查看运行效果呢?怎么样在手机上运行呢?

预览项目

有两种方法:在微信开发者工具的模拟器中预览和真机上预览。

点击工具栏上的「编译」按钮,即可在左侧的模拟器区域看到小游戏的运行效果。

点击「编译」按钮旁边的「预览」按钮,通过微信扫一扫二维码,即可在手机上预览这个「打飞机」小游戏。

这是一个不错的小游戏,左右滑屏即可操作我方飞机横向移动。必须小心避过敌机,否则生命值会损耗,当没有生命时游戏就结束了。我方炮弹是自动发射的,当炮弹撞上敌机,屏幕上就会出现一个爆炸的效果。大家有没有想过这个效果是怎么实现的?

每炸掉一个敌机得一分。有对抗,有分数,这基本是一个完备的小游戏了。唯一设计上不足的地方,是当我方飞机不动时,自动发射的炮弹将前方敌机扫清了,敌机是很难撞到我方飞机的。

现在我们放下游戏,稍后还会深入讲解它的实现,我们接着看微信开发者工具的功能。预览有两种选择:二维码预览和自动预览。

默认是二维码预览,待项目编译并且代码包上传完成后,二维码自动呈现,微信扫一扫即可在手机上查看。但每次修改后都要拿起手机扫码,这在开发中实在有些麻烦。

另一个自动预览的功能,是微信后来添加的。单击自动预览分栏下的「编译并预览」按钮,手机上将自动打开游戏。

自动预览这个功能可以避免每次扫描二维码的麻烦。但有人发现,有时候发现单击「编译并预览」,手机上没有反应,这是怎么回事呢?

自动预览功能至少需要微信扫描过一次预览二维码。先使用一次二维码预览功能,再使用自动预览就没有问题了。如果微信换帐号重新登陆过或微信 App 重装过,也需要重新扫码。

自动预览功能,是手机微信上已经测试过一次的小游戏项目,与微信开发者工具之间建立了通讯连接而达成的。并且这种链接与在不在同一个局域网没有关系,即使电脑用 Wifi,手机用 4G 也不影响。两者之间的通讯就像两个微信好友之间的消息收发一样,一个发出去,另一个收到,两者之间虽然没有长连接,但基本可以保证「实时」同步。

有的开发者说,这个自动预览功能虽然不用扫码,但每次都要点一遍预览 -> 自动预览 -> 编译并预览,这个工作真是重复枯燥单调无价值。好吧,笔者也承认这一点,甚至有时候在点击了「编译并预览」后,都要等上老半天。

为了解决这个问题,我们可以使用微信开发者工具提供的外部调用功能,监听项目文件变动,以此实现真正的自动预览。

自动预览项目

微信开发者工具调用功能,提供两种方式:HTTP 服务与命令行。我们先看一下 HTTP 服务怎么使用。打开微信开发者工具,选择菜单设置 -> 安全设置 -> 安全,开启服务端口,并记录下这个端口号:

例如笔者开启的端口是 23374。然后在浏览器中输入:

<code>http://127.0.0.1:23374/open?projectpath=/Users/石桥码农/WeChatProjects/minigame-1/<code>

projectpath 代表项目地址,/Users/石桥码农/WeChatProjects/minigame-1 是笔者创建的小游戏项目目录,读者在执行时需要换成自己的地址。

当尝试打开这个链接时,微信开发者工具将被唤起并自动打开 projectpath 参数指定的小游戏项目。这就是 HTTP 服务,open 代表打开,在微信官方文档上还有其它命令及使用说明。

这种方式有一个缺陷,使用时微信开发者工具必须是已经启动的,还有上面的那个服务端口每次重启开发者工具后都会变化。使用 HTTP 服务实现真正的自动预览并不是一个好的选择。

除了 HTTP 服务,还可以选择命令行。命令行不需要预先启动,也无关端口。当笔者在终端中执行这行命令时:

<code>/Applications/wechatwebdevtools.app/Contents/MacOS/cli open /Users/石桥码农/WeChatProjects/minigame-1/<code>

微信开发者工具同样会被唤起并主动打开同样的小游戏项目。这是 mac 系统上的工具地址,在 windows 系统上路径会有所不同,这取决于软件在系统上安装的路径。命令行工具地址为:

<code>macOS: /Contents/MacOS/cli Windows: /cli.bat/<code>

例如,在 windows7 上默认微信开发者工具的安装地址为:

<code>C:/Program Files/Tencent/微信web开发者工具/<code>

那么对应的项目开启命令就是:

<code>C:/Program Files/Tencent/微信web开发者工具/cli open /Users/石桥码农/WeChatProjects/minigame-1/<code>

上面我们演示的是项目开启,如果是自动预览,命令名称是 auto-preview,以 mac 为例需要执行的完整命令则是:

<code>/Applications/wechatwebdevtools.app/Contents/MacOS/cli auto-preview --project /Users/石桥码农/WeChatProjects/minigame-1/<code>

执行这条命令后,如果最近小游戏项目在手机上运行过,手机便会自动打开项目。

我们知道,Node.js 有一个 fs 模块,fs.watch 方法可以实现对一个目录的监控。当监控到项目文件有变动,就自动执行上面的那条命令,是不是就能实现真正的自动预览呢?

为了验证这个想法,我们在项目根目录下新建一个 watch.js 文件,内容如下:

<code>const fs = require ("fs"); let { exec } = require ("child_process"); fs.watch ( `/Users/石桥码农/WeChatProjects/minigame-1`, () => { exec ( `/Applications/wechatwebdevtools.app/Contents/MacOS/cli auto-preview --project /Users/石桥码农/WeChatProjects/minigame-1`, { cwd: `/Applications/wechatwebdevtools.app/Contents/MacOS/` }, (error, stdout, stderr)=>{ console.log (error,stdout,stderr); } ) } )/<code>

在上面代码中,我们使用了 child_process 模块,它的 exec 方法允许我们在 js 中执行一条命令。调用语法为:

<code>child_process.exec (command [, options][, callback])/<code>

exec 有三个参数:

command,字符串,需要运行的命令,参数用空格分隔options,键值对象,参数之一 cwd 表示子进程的工作目录callback,回调函数,形式为 (error, stdout, stderr)=>{}

用于实现真正的自动预览的代码写好了,现在我们只要在终端里执行 node watch.js 就可以了。当项目文件有修改时,手机微信即会打开项目。如果微信开发者工具未登陆,终端将会打印出错误:

<code>[error] { code: 10, message: \'Error: 错误 需要重新登录 (code 10)\' }/<code>

唯一美中不足的是,这个自动预览会让手机微信频繁打开项目,在手机上能累计打开十几层小飞机游戏,这种现象在手动操作时是很难出现的。可以使用 debouce 防抖函数改善监测功能,具体可以查看笔者的源码。

到目前为止,我们已经创建了第一个小游戏项目,并在手机上实现了预览,还结合微信开发者工具的外部调用功能实现了真正的自动预览。微信开发者工具一直都在进化,作者是以 1.02 版本撰写的本课内容,关于项目创建面板的选项设置,及编译、预览功能的设定等,这些以后可能会有变化,但大致功能不会改变。如果读者朋友在阅读时遇到了软件界面与课程教程不完全一致的问题,可以参考官方文档上的这个地址:

<code>//developers.weixin.qq.com/minigame/dev/guide/# 安装并启动开发者工具/<code>

在成功创建并运行了项目之后,接下来让我们花点时间熟悉一下小游戏项目的文件目录结构,这对于接下来的学习很有帮助。

熟悉项目结构

我们看一下上一步创建的「打飞机」项目,它在微信开发者工具资源管理器中的截图是这样的:

其中,game.js 是游戏主文件,game.json 是游戏配置文件,project.config.json 是项目配置文件。audio 目录存放的是音频文件,images 目录存放的是本地图片。js 目录文件较多,包括以下子目录及文件:

<code>js 目录 ├── base // 定义游戏开发基础类 │ ├── animatoin.js // 帧动画的简易实现 │ ├── pool.js // 对象池的简易实现 │ └── sprite.js // 游戏基本元素精灵类 ├── libs │ ├── symbol.js // ES6 Symbol 简易兼容 │ └── weapp-adapter.js // 小游戏适配器 ├── npc │ └── enemy.js // 敌机类 ├── player │ ├── bullet.js // 子弹类 │ └── index.js // 玩家类 ├── runtime │ ├── background.js // 背景类 │ ├── gameinfo.js // 用于展示分数和结算界面 │ └── music.js // 全局音效管理器 ├── databus.js // 管控游戏状态 └── main.js // 游戏入口主函数/<code>

这上面的所有文件,只有 game.js 与 game.json 对于小游戏是必须的。js 目录下的 base、libs、npc 等子目录,并不是每个小游戏项目都必须有的。

关于小游戏所有的配置,都是在 game.json 文件中完成的,下面我们重点看一下这个文件。

在 game.json 里最常用配置字段是 deviceOrientation 与 showStatusBar:

<code>{ "deviceOrientation": "portrait", "showStatusBar": false }/<code>

deviceOrientation 属性用于设定屏幕方向,有 portrait 竖屏、landscape 横屏两个选项,默认为 portrait。showStatusBar 设置是否显示系统状态栏,默认为 false,即全屏。系统状态栏是手机顶部有 Wifi、电量标志的那一行区域。

现在我们对项目结构也有了初步的理解了,接下来我们了解小游戏如何发布吧,毕竟我们在本地开发游戏,就是为了最终上传发布。

微信开发者工具栏上有一个「上传」按钮:

单击这个按钮即将本地所有源码压缩成代码包,并上传至微信服务器。当用户在微信里访问小游戏时,是微信服务器在向用户提供服务。

这里有一点需要注意,代码包有大小限制。目前每个小游戏允许上传的单包大小是 4mb。如果使用分包加载技术,所有分包加起来最大不允许超过 8mb。4mb 很小,有时候一张高清图片就会超过这个限额。

但这个大小已经比小程序的限额大了一倍了。目前微信小程序单包大小限制为 2mb。这些限制随着手机性能的提升、技术的进步和企业之间竞争的加剧,以后可能会逐步提高。

虽然代码包有大小限制,但是在项目里大多数资源文件,如图片、音频、视频等资源,是以网络链接的存在游戏中使用的,并不占用配额。主要的内容是代码文本,压缩之后最大能减少 70% 的体积,所以软件包大小并不值得担心。

在软件包上传后,开发者可以在微信公众平台看到待提交审核的版本。在线提交审核,待审核通过后,小游戏就可以正式发布了。

项目到提审、发布这一步已经很简单了。最重要的步骤还是开发与调试,尤其在开发中遇到 bug 时,需要尽快找到并解决问题。关于这一块,微信开发者工具也提供了方便、全面的调试功能。

如何调试代码

js 是小游戏最主要的开发语言,小游戏调试主要是调试 js 代码。js 作为一种寄宿语言,调试方法依赖寄宿环境。在传统的网页开发中,可以这样调试代码:

使用 window.alert () 弹框展示使用 document.write () 方法将内容写到 HTML 页面中使用 innerHTML 写入 HTML 元素,在页面上呈现使用 console.log () 写到浏览器控制台,这是最常见的一种方式

在小游戏开发中,主要使用 console 面板调试 js 代码。使用 console.log、console.error 等方法在 console 面板打印内容。

鉴于小游戏宿主环境的差异,有些 bug 在微信开发者工具中不存在,在手机上却存在,这时候如何在手机上调试呢?

在手机上调试,当小游戏运行后,点击屏幕右上角胶囊按钮组中的「…」按钮,选择「打开调试」。此时小游戏会退出重启,待重新打开后,屏幕右下角会有一个 vConsole 按钮。点击这个 vConsole 按钮,便可以看到亲切的 Console 面板及代码中使用 console.log 打印的内容了。

有时候有些 bug 是在用户的手机上发现的,在开发工具中和在自己的手机上都复现不了,这时候排查问题,可以使用工具栏中的「真机调试」功能。单击该按钮,会生成一个二维码,将这个二维码发给用户。当用户扫码打开游戏后,开发者的微信开发者工具会自动打开一个新的调试窗口,用户手机上的 vConsole 输出会自动同步到这个窗口来。

通过远程真机调试,用户在他的手机上进行一些操作,运行的是开发者本地的代码,相应的打印信息开发者在本地都能看到。这是一个很方便的排查用户 bug 的调试方法。

在使用该功能时,有一点需要注意,就是用户必须是小游戏帐号的测试用户,不然用户是无法运行开发者的测试代码的。登陆微信公众平台(//mp.weixin.qq.com),使用管理员身份可以将用户微信添加为体验者,添加之后就可以进行远程调试了。

本节课我们学习了如何创建并运行第一个小游戏项目,还学习了如何在微信开发者工具中及手机上查证问题、调试代码,调试是每个程序员都必备的技能之一,在接下来的学习中将发挥重要的作用。下一课我们将深入探究「打飞机」项目的源码,看一看飞机是如何飞行的,又是如何控制移动的,爆炸效果是如何实现的等等。

本课源码

<code>//git.weixin.qq.com/rxyk/wegame0to1-1/repository/archive.zip?ref=lesson2/<code>

源码下载后解压,打开微信开发者工具,选择小程序项目 -> 小游戏,单击「+」号,选择「导入项目」,如下所示:

将 AppID 修改为自己的小游戏帐号 AppID,完全后即可查看调试源码。以后各章方法同。

这篇属于「小游戏从 0 到 1」50 课的一部分,有什么问题欢迎留言,也欢迎群内讨论。

2019 年 5 月 7 日