微信小游戏 - 初体验
| 导语 现在,对于想玩web游戏的大佬们来说,除了浏览器,还有微信平台可以选择了。在月活用户近9亿的社交平台上做小游戏,是胆战心惊了点,毕竟游戏脱离控制、变身国民爆款可能是分分钟的事。
前言
拳皇KO小游戏以打地鼠为契机,探索微信群好友之间互动玩法的可能性。本文整理了近两个月来开发拳皇创意小游戏的过程,总结收录了一篇小游戏的开发体验日志,希望本文能给对小游戏开发同样感兴趣的读者们提供一点点灵感。由于在下没有开发大型游戏的丰富经历,开发拳皇小游戏时只能全凭直觉,如果大家对这款游戏有一些想法或建议的,欢迎在留言区评论~
这两个月间,小游戏开发工具和API处于快速迭代中,如果本文章与 小游戏官网文档 有出入,请以官网的为准。
快速创建demo
和许多传统的网页游戏类似,微信小游戏(以下简称小游戏)的技术核心是 javascript和canvas。也就是说,只要一款网页游戏是基于这两个技术点的,基本上都可以很快速地移植到微信小游戏上(注意移动端没有键盘鼠标就行了)。
在微信平台,小游戏提供了一个全局的canvas,开发者们可以在项目的入口文件game.js中获取到。开发者全程只需编写javascript,而无需和 DOM 打交道,这是小游戏的特点。现在我们开始新建一个demo,来体验下小游戏吧。
项目创建步骤:
1、新建项目文件夹test-minigame。
2、下载并使用 小游戏开发者工具,点击项目->新建项目,选择第一步时新建的目录test-minigame,填写appID(需要微信的同事将已有的小程序appID转为小游戏类型)和项目名。如图,注意把下方的“建立普通快速模板”选项去掉,点击确认即完成项目的初始化,开发工具会将appID等配置写入project.config.json中。
[ 配置项 ]
3、此时会看到工具出现错误提示,别担心,是因为我们缺少了游戏配置文件和入口文件。我们在项目下创建入口文件game.js,其内容为空即可。同时,创建配置文件game.json,其内容如下:
{
"deviceOrientation": "portrait",
"networkTimeout": {
"request": 5000,
"connectSocket": 5000,
"uploadFile": 5000,
"downloadFile": 5000
}
}
完成后点击编译或ctrl+s保存,项目的配置到这里就完成了。
4、接下来,需要引入微信端提供的 adapter库 ,才能访问和操作全局的canvas。将下载好的adapter库拷贝到项目下,并在入口文件game.js中引入,来打印出小游戏中自带的全局canvas:
require("weapp-adapter.js");
console.log(canvas);
当控制台打印出canvas时,则表示已引入成功:
[ 控制台信息 ]
5、到这里,我们已完成了小游戏的初始demo,接下来可以自由地在canvas上画画了。随手一个Hello World致敬一下(手动狗头)。
require("weapp-adapter.js");
console.log(canvas);
let canvasCtx = canvas.getContext("2d");
canvasCtx.font = "20px 微软雅黑";
canvasCtx.fillStyle = "#369";
canvasCtx.fillText("Hello World", 30, 50);
这是在下之前写过的H5吃豆人,亲测可以很轻松地移植过来。
[ pacman ]
有想法的同学同样可以在茶余饭后把canvas注册到新引入的Pixi.js,three.js等游戏库,来开启自己的小游戏之旅~
开发记录及所遇问题
拳皇创意小游戏使用到的引擎是create.js,所以本次搜集到的问题不少也是关于该引擎在微信平台上的表现的。可以扫描下方菊花码体验一下小游戏~
[ 小游戏体验入口 ]
1、全局页面管理:game.js 是小游戏的唯一入口,拳皇小游戏使用 require 的模式来处理页面加载。页面跳转处理逻辑如下:在新的页面资源加载完成后,清除画布、事件绑定和定时器,然后绘出新的页面。
2、游戏核心玩法:拳皇小游戏的核心玩法类似经典的打地鼠,通过点击冒出的正确牌子来得分。
[ 拳皇游戏界面 ]
- 游戏的基本思路是使用全局时间轴的方式来管理动画。关于动画,可以将牌子的运动分解为多种状态以方便管理:“hidden”(藏在地洞的时候)、”ready”(准备上升)、“raiseUp”(牌子上升)、“hold”(在最高处悬停的状态)、“fallDown”(牌子下降)、“punched”(被打击)。所有木牌初始状态为“hidden”,当随机数达到某一概率时,该牌子状态切换为“ready”,此时做头像、头像id和木牌颜色的切换,切换后转为“raiseUp”状态,上升到最高处时,切换到“hold”状态,hold状态在可控倒计时N毫秒后切换为“fallDown”状态,最后转为“hidden”,完成一个周期。期间被点击时立即转为“punched”状态,附带打击效果后转为“hidden”状态。
[ 木牌流程图 ]
- 使用以下数据结构记录牌子对象的各种信息,包括但不限于状态status、当前位置current.x、current.y、头像、得分id、木牌颜色,使用定时器来对6个木牌对象进行轮询,依次修改每个牌子的动画帧,即改变牌子的位置和状态,以完成动画。
- 在 touch 事件时,获取点击位置并与牌子的当前位置相比较,来判断打击的位置并将对象的状态切换为“punched”。
- 其它方面,设置牌子冒出的概率、最低地洞数规则、难度叠加、处理得分与危险头像冒出比例均衡化等信息。
3、关于点击事件:create.js中封装的监听事件 touch 可以非常方便地完成某一对象的交互监听。拳皇小游戏使用到了这个接口。但createjs中的touch.enable会与wx.onTouch系列冲突到,两者不能同时使用。另外,create.js对 touch 事件进行了冒泡等复杂逻辑的处理,这会导致在某些情景下的性能大幅度下降。比如在拳皇的游戏进行过程中,需要频繁地点击木牌,这在安卓手机甚至iphone上都会出现不同程度的卡顿。针对这一点,拳皇在游戏进行中有选择性地回避了createjs的touch接口,改为使用了微信的原生点击wx.onTouchStart,在捕获点击位置后手动判断打击的具体对象。游戏结束后再使用 createjs.Touch.enable进行点击事件的恢复。
4、在封装Promise函数同步加载图片时,image的nativeWidth属性不兼容,需以image.width作为图片加载成功的依据。
5、关于字体的问题:canvas字体斜体和加粗可能存在兼容问题,需要实际测试。关于自定义字体,字库大小一般为2M左右,接近一个普通小游戏的大小了,所以引入字库还是要慎重~。
6、字体模糊和图片锯齿等问题。这是canvas被强行拉长导致的,小游戏平台下canvas会被系统伸展到满屏,默认width为320的canvas被拉到750自然会出现模糊。这里需要全局先调整下canvas的宽和高来达到高清的效果,代码如下:
let width = window.innerWidth;
let height = window.innerHeight;
let devicePixelRatio = window.devicePixelRatio;
canvas.width = width * devicePixelRatio;
canvas.height = height * devicePixelRatio;
canvas.style.width = width;
canvas.style.height = height;
7、(2017-10-28及之后的版本中已修复)小游戏分享成功后(或者手机锁屏重开后),出现的黑屏问题。这里是画布被清空了导致的,移动端的画布默认是黑色的(开发工具是白色底的),所以会看到黑屏。解决方法建议:使用wx.onShow()方法,在每次小游戏重新进入的时候手动更新画布,或者设置定时器短时间内不断更新画布。
8、手机适配问题:标准设计稿尺寸为 750px:1334px,在iphone 6等手机上可以完美适配。但在部分长屏的手机(如iphone X,三星等部分手机)上可能会出现底部黑边,将设计稿做长是最快速的解决方法,如将设计稿调整为 750:1700。嗯这样适配就做完了吗?如果你忘记了 iphoneX 顶部的刘海,那可是很伤脑筋的。拳皇小游戏中,也有一些场景需要做特殊处理,如游戏页面的顶部分数栏:
[ iphoneX_适配后 ]
这里的逻辑是判断 iphoneX 机型,并对分数栏进行下移操作。判断的代码如下:
let reg = /iphone\\s*x/i; // iphone X
const systemInfo = wx.getSystemInfoSync();
if (systemInfo.platform === "ios" && reg.test(systemInfo.model) === true) { // 判断为 iphoneX
// 适配逻辑
}
9、关于图片资源:在个人的理解中,游戏对资源的处理主要分为两种,盗用其它领域的专用词:集中式和分布式。集中式是指将游戏的全部,或者大部分主要的图片打包,在第一次进入游戏时全部加载下载完,而后才开始游戏。分布式则是把资源分割开,如按照一个个页面分割成多个包。在用户访问具体的页面时,才进行加载。
- 集中式的优点是代码逻辑易维护,缺点是首屏加载时间特别长。
- 分布式的优点是首屏渲染极快,可以防止用户因等待而流失,缺点是遇到弱网情景时,维护成本较高,具体见第10点(弱网处理)。
10、弱网处理:使用“分布式”来管理图片资源,在遇到弱网情况下会出现一些问题:如在点击跳转页面时,新页面的图片加载失败导致的卡死问题。“分布式”的方式让拳皇小游戏变成了一个个“网页”,但小游戏中并没有刷新某个“网页”的按钮,一旦在中途出现加载失败,那用户看到的就是一个卡死了的小游戏。因此,需要为每一次的图片加载增加错误处理,让游戏在加载失败后能有“刷新”的能力。
11、测试环节:移动端存在网络不稳定和带宽限制等问题,小游戏需要经过弱网测试。可以开启3G信号进行体验,在许多加载耗时较高的地方及时增加提示和处理网络中断,以优化用户体验。另外,还要保证在断网重连后能继续体验游戏。
最后一点想法
在用户体验上,移动端具有便捷的优势,但在物理上,移动端可不止缺了个鼠标键盘,相对于浏览器,它还存在着带宽限制和信号不稳定等问题。另外,毕竟是站在巨人的肩膀上,如果是计划推广的小游戏,在考虑手机性能时还是得以国产大众安卓机的性能为准。
出于这几点,对于技术过于复杂的游戏,比如大型3d渲染类型,或者游戏本身素材非常丰富的,可能不太合适接入到移动端,毕竟在遇到带宽限制或弱网压力测试时,用户体验可能会大幅下降。以上这些是游戏预研早期阶段需要考量的点。
Q&A
Q: 早在小游戏之前,小程序里已经存在canvas了,为何无法完成这样的游戏?
A: 小程序中的canvas和小游戏的canvas差别很大,小程序下的canvas功能和公开的接口都十分有限,基本无法完成一般的HTML5游戏;而小游戏下的canvas对象则几乎接近网页版canvas,能进行动画复杂的游戏开发。
Q: H5网页游戏可以很方便地移植到微信小游戏,那么微信小游戏是否也可以快速地移植到H5上?
A: 这里需要具体问题具体分析,微信小游戏拥有的资源文件下载功能、社交功能等都是H5所不具备的,移植过去意味着与这些相关的功能都需要砍掉,另外用户的游戏数据、登录方式等,都有可能增加后台开发的工作量。这里不排除工作量等同于重新开发的可能性。
---------------------------------------------------------------
原文作者:腾讯工程师黄智豪。
来源:腾讯内部KM论坛。