一款受扫雷启发的邻近游戏。
为您带来 squoosh.app 的团队又回来了!这次,我们构建了一款名为 PROXX (proxx.app) 的基于 web 的游戏。PROXX 是一款受传奇游戏扫雷启发的邻近游戏。游戏背景设定在太空,您的工作是找出黑洞的位置。它适用于各种设备,从桌面设备到功能手机。用户可以使用鼠标、键盘、方向键,甚至屏幕阅读器来玩这款游戏。
我们的基准
在构建这款游戏之前,我们为应用程序设定了以下目标和预算
- 相同的核心体验:所有设备的功能必须相同
- 无障碍:鼠标、键盘、触摸、方向键、屏幕阅读器
- 高性能:
- 初始有效负载小于 25kb
- 在慢速 3G 网络上,TTI(可交互时间)小于 5 秒
- 一致的 60fps 动画

Web Workers
该游戏由 4 个主要实体组成:核心游戏逻辑、UI 服务、状态服务和动画图形。由于我们从一开始就知道我们必须在主线程上运行大量动画图形,因此我们将游戏逻辑和状态服务移至 Web Worker,以尽可能保持主线程空闲。
构建时预渲染
我们的 UI 是使用 Preact 构建的,因为它使我们能够实现初始有效负载小于 25kb 的积极目标。为了提供良好的初始加载体验,我们决定预渲染我们的第一个视图。我们在构建时使用 Puppeteer 访问顶层页面,并让 Preact 填充 DOM。然后将生成的 DOM 序列化为 HTML 并另存为 index.html
用于动画的 Canvas,用于无障碍功能的(不可见)DOM
我们使用 WebGL 在 canvas 中渲染游戏图形。一个 canvas 负责背景动画,另一个 canvas 负责顶部的游戏网格。我们还有一个 HTML 表格,其中包含用于无障碍功能的按钮,该表格位于这两个 canvas 的顶部,但设置为不可见(opacity: 0)。即使您看到的是游戏状态的 canvas 渲染,玩家也在与不可见的 DOM 表格交互,这使我们能够附加事件侦听器并依赖浏览器的焦点管理。
通过将 DOM 元素保留在 canvas 中,我们能够利用浏览器内置的无障碍功能。例如:通过在我们的游戏表格上设置 role="grid"
,屏幕阅读器可以播报焦点单元格的行和列,而无需我们实现该功能。
用于捆绑和代码拆分的 Rollup
该应用程序的总大小压缩后为 100KB。其中,20KB 用于初始有效负载 (index.html)。我们在此项目中使用 Rollup.js。我们在主线程和 Web Worker 之间共享依赖项,Rollup 可以将这些共享依赖项放在一个单独的块中,该块只需加载一次。其他捆绑器(如 webpack)会复制共享依赖项,从而导致重复加载。
支持功能手机
智能功能手机(如 KaiOS 手机)正迅速普及。这些设备的资源非常受限,但我们尽可能使用 Web Worker 的方法使我们在这些手机上的体验也具有高度响应性。由于功能手机配备不同的输入界面(方向键和数字键,没有触摸屏),我们还实现了基于按键的界面。

下一步
为了赶上 2019 年 Google I/O 大会,我们非常忙碌地构建了这款游戏,因此我们将抽出一些当之无愧的时间休息一下,但计划回来就游戏的每个领域提供更深入的文档。
在那之前,请观看 Mariko 在 I/O 大会上就此项目所做的演讲。
您可以在 proxx GitHub 存储库 中浏览代码。
干杯!Surma、Jake、Mariko