我喜欢参加 游戏马拉松,游戏开发者们聚在一起在很短的时间内制作游戏。我想将我之前的一款游戏马拉松游戏 Metal vs Hipsters **移植到移动网页和 Firefox OS** 上,这会很酷。
适应移动端
我的 **起点** 是一款为 **桌面** 构建的 HTML5 游戏。它有固定分辨率,由键盘控制,等等。需要进行一些小的(和大的!)调整才能将其变成一款移动游戏。
该游戏使用开源游戏引擎 Phaser,因此此处显示的一些代码将使用 Phaser 的 API。
你可以在这里查看并玩最终的移动版本 这里。
可视化游戏
我使用的第一个工具是 Firefox 的 **响应式设计视图**。它允许你裁剪屏幕并模拟不同的屏幕尺寸。你可以从 Firefox 浏览器工具下拉菜单中的 **工具>Web 开发者>响应式设计视图** 访问它。
另一个工具是真正的 **手机**!我有一台安装了多个浏览器的 Android 设备。通过在localhost 中运行游戏,然后将我的手机连接到我的本地 Wi-Fi 网络,我可以在我的电脑的 IP 地址上访问游戏。
这将带来第一个问题……
缩放
这是游戏在响应式设计视图中以 320×480 尺寸(横向)未缩放时的糟糕效果。

解决方案是使用 Phaser 的 ScaleManager 来缩放游戏,使其适合屏幕(如果需要,使用 Letterboxing)
var BootScene = {
init: function () {
// make the game occuppy all available space, but respecting
// aspect ratio – with letterboxing if needed
this.game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
this.game.scale.pageAlignHorizontally = true;
this.game.scale.pageAlignVertically = true;
},
// ...
};
此外,在原始游戏中,我使用了一个包装的 div 元素来将游戏居中在页面上,并添加了一些填充、文本等。现在,所有这些页面元素都必须删除,才能让游戏访问所有可用的屏幕空间。

现在好多了!
输入
下一个问题是 **控制**。我的桌面游戏使用箭头键来移动和跳跃主角。我选择包含一个虚拟游戏手柄,所以我创建了一个新的图像。

我需要三个按钮:两个用于向左和向右移动,另一个用于跳跃。我创建了三个 Phaser.Button 实例。这是在一个辅助函数中完成的。
var upBtn = new Phaser.Button(this.game, ...);
由于 Phaser.Button 没有告诉我们按钮是否被按下的标志,我需要自己添加它。这可以通过监听 inputDown 和 inputUp 事件来轻松实现。
[leftBtn, rightBtn, upBtn].forEach(function (btn) {
// register callbacks
btn.isDown = false;
btn.events.onInputDown.add(function () { btn.isDown = true; });
btn.events.onInputUp.add(function () { btn.isDown = false; });
我们还需要监听 Up 按钮的 inputDown 事件,以使角色能够跳跃,因为在桌面游戏中,跳跃是由 keyDown 事件触发的。
btnUp.events.onInputDown.add(this.tryJump, this);
对于移动,只需要检查我已经设置的 isDown 标志,以及之前对 this.keys.left 键盘键的检查。
if (this.keys.left.isDown || this.keys.btnLeft.isDown) {
this.hero.move(-1);
}

然后,该游戏可以在我的 Android 设备上的 Firefox 和 Chrome 移动浏览器中玩。但是,测试游戏时发现更多问题……
重新定位元素
我在玩游戏时注意到,我自己的手指会遮挡住游戏角色。这是一个大问题,因为它让游戏变得非常难玩和令人讨厌。
解决方案是让游戏组更大(100 像素),然后向上移动所有游戏元素。

允许点击其他区域
我还发现,点击 **点击重新开始** 文本有点难。因此,我让 **游戏结束** 文本(更大)也能点击。
// create game over text
var banner = this.game.add.text(...);
banner.inputEnabled = true;
banner.events.onInputUp.add(this.restartGame, this);
除此之外,我用 **点击重新开始** 替换了 **点击重新开始**,这在移动环境中更有意义。
改造启动画面
启动画面也需要一些调整,因为它最初是硬编码为固定分辨率的。
第一步是调整背景的大小,使其占据整个屏幕空间,同时保持其纵横比。
.overlay {
background-size: cover;
}
然后我调整了一些现有文本和按钮的大小,并删除了控制帮助图,因为它指的是桌面箭头键。

可玩性
最后,游戏完全可玩了……但现在它 **太短了**!原始游戏有五波预定义的敌人。这对于游戏马拉松来说没问题,因为大多数人只会尝试很短时间的游戏(实际上有成千上万的游戏可以尝试)。
对于移动游戏来说,一分钟的游戏时间是不够的。因此,我调整了游戏代码,去掉了预定义的波,使它们 **随机且无限**。无限的游戏时间!
转化为 Firefox OS 应用
一旦游戏运行良好且玩起来很有趣,就该把它变成一个 Firefox OS 应用了。
在模拟器中作为托管应用运行
第一步是在 Firefox OS 模拟器中将其作为托管应用运行。
你可以从 WebIDE(**工具>Web 开发者>WebIDE**)中获得模拟器,方法是在右侧边栏中点击 **安装模拟器**。我安装了 Firefox OS 2.6 版本。

要创建一个托管的 Web 应用,我们需要一个在 JSON 文件中引用图标的图标,其中包含一些元数据。该文件被称为 Web 应用清单。
虽然你可以提供不同大小的图标,但最低要求是拥有一个 128x128 的图标。
![]()
该 清单文件只是一个 JSON 文件,位于我们的应用的根目录下。它包含有关我们的应用的一些元数据:应用的名称、作者、区域设置等。这是我的 manifest.webapp 的初始版本。
{
"name": "Metal vs Hipsters",
"description": "Arcade game",
"launch_path": "/index.html",
"icons": {
"128": "/images/icon-128.png"
},
"developer": {
"name": "Belén 'Benko' Albeza",
"url": "http://www.belenalbeza.com"
},
"default_locale": "en",
"version": "1.0.0"
}
要在 WebIDE 中的模拟器中运行 Metal vs Hipsters,请点击 **打开托管应用**,然后指向正在运行的本地服务器中清单文件的位置。


现在我的项目已经添加了……

……我们终于可以在模拟器中运行它了。

在手机上作为打包应用运行
在模拟器中运行游戏很酷,但没有什么比 **在真实的设备上玩你的游戏** 更棒的了。除了托管应用之外,我还想为 Firefox 市场创建一个 打包应用。
我有一台装有 Firefox OS 的 Xperia Z3 Compact 手机,准备好了。通过 USB 连接并启用 开发者模式 后,它在 WebIDE 中的 USB 设备 列表中列出。

创建打包应用的工作流程与我为托管应用描述的非常相似。在 WebIDE 中,点击 **打开打包应用**,然后指向游戏的文件夹。

选择我的手机作为设备,我点击了顶部的“播放”按钮,然后……轰!

现在游戏可以在手机上运行了,我可以利用 **仅适用于应用的某些设置**,而不仅仅是移动网站。我希望游戏能够以 **全屏** 方式运行(无需任何提示!),并且我希望强制 **横向** 方向。我能够通过在清单文件中添加一些更多设置来做到这一点。
{
...
"fullscreen": "true",
"orientation": ["landscape"]
}

本地资源
现在我已经将游戏构建为打包应用,我需要包含运行它所需的所有资源。该游戏使用来自 Google Fonts 的一种字体 Bangers。为了游戏马拉松,我使用 Google 建议的一种方法包含了字体:链接到他们服务器上的 CSS 文件,其中包含字体定义。
<link href='https://fonts.googleapis.ac.cn/css?family=Bangers'
rel='stylesheet' type='text/css'>
如你所见,这对于打包应用来说是行不通的,因为玩家有可能在 **离线** 状态下第一次启动游戏,并且他们将无法访问该字体。幸运的是,这些字体也可以下载并与你的项目一起分发(开源万岁!),所以我做了这件事。
我将 Google 的 CSS 文件的内容复制到我自己的 CSS 文件中,将 src URL 更改为指向我的本地副本,一切都设置好了!
@font-face {
font-family: 'Bangers';
font-style: normal;
font-weight: 400;
src: url(../fonts/Bangers.woff2) format('woff2');
}
进入 Firefox 市场
打包用于 Firefox OS
打包应用通过一个包含我们应用程序的单个 **zip 文件** 进行分发。我使用了一个任务运行器 Gulp 来自动化开发的某些部分;所以我添加了一个新的任务来自动生成这个 zip 文件。我使用了 gulp-zip 模块。
npm install gulp-zip --save
gulp.task('release', ['dist'], function () {
var data = JSON.parse(fs.readFileSync('./package.json'));
var filename = data.name + '-' + data.version + '.zip';
return gulp.src('./dist/**/*')
.pipe(zip(filename))
.pipe(gulp.dest('.'));
});
提示:生成后,始终 解压缩你的文件以确保所有文件都在那里!
将你的应用提交到 Firefox 市场
你可以 将你的应用提交到市场,但你需要先创建一个帐户。
登录后,我选择 **免费应用**,然后选择 **打包应用**,并上传了 zip 文件。然后,清单文件和应用文件被验证了。

有一些 **关于 CSP 的警告**,但由于游戏不需要特殊权限(例如访问联系人),所以它会没事的。这些 CSP 警告是由于 Phaser 在使用位图字体时使用了 document.createElement('script')。由于我的游戏没有使用这些字体,所以如果我真的需要为我的游戏获得特殊权限,我可以简单地对 Phaser 进行猴子补丁并删除那部分代码。
为了提交游戏,我必须提供一个隐私政策。该游戏没有收集或存储任何类型的數據,所以我写下这点了。
This application does not store or collect personal information or any kind of user data.
如果你的游戏确实收集了數據,请查看 MDN 中的 隐私政策指南,以帮助你起草一个。
我还需要一些 320x480 的截图。

作为最后一步,我被要求设置 **内容评级**。提交表单将带你到 IARC 工具,这是一个向导,可以帮助你根据一些标准对你的游戏进行评级。由于我的游戏中包含一种幻想暴力——我想一把燃烧着火焰的吉他摧毁嬉皮士和蛋糕算作这样——最终被评为 PEGI-12。

所有都完成了!现在要等一等,直到它被审核并通过。
更多调整和潜在的改进
并非所有浏览器都对功能或文件格式具有相同的支持。在不同设备上测试游戏时,我发现 Safari 在 iOS 上存在一些问题:网页字体无法正确加载,背景音乐曲目没有播放。问题在于 iOS 版 Safari 不支持 Woff 和 OGG 作为字体和音频的格式(提示:您可以在 Can I use? 中查看这些信息)。我所要做的只是将这些资源添加到 TTF 和 MP4 中,就能在 iPad 上玩游戏了。
游戏应该可以在主要的移动浏览器(Firefox、Chrome 和 Safari)上运行。我希望 IE/Edge 会出现问题,但我手头没有 Windows 设备可以进行测试。
虽然当前版本在浏览器中玩起来很有趣,但还有其他可以使游戏变得更好的改进:在主角被杀时使用 振动 API,使用 localStorage 存储高分,允许 直接从游戏网站安装应用程序,支持网页版 离线模式 等。
玩吧!
该游戏已在 Firefox Marketplace 中提供下载。您也可以从您的移动浏览器在此处玩游戏,以及获取完整的GitHub 上的源代码。
我希望这篇文章能帮助您将 HTML 5 游戏移植到移动设备和 Firefox OS 上。大多数情况下,它们不需要太多调整,您就可以扩大您的玩家基础。另外,在通勤时玩自己的游戏是无价的 :)
关于 Belén Albeza
Belén 是一位工程师和游戏开发者,在 Mozilla 开发者关系部门工作。她关心 Web 标准、高质量代码、可访问性和游戏开发。

一条评论