GameMaker Studio (1/2) 在 KaiOS 上的尝试

发布于 2019-07-22  2971 次阅读


高考考完以后闲来无事,就去闲鱼捡了个八成新的诺基亚 8110 4G(花费 220 元)把玩了一下,顺便试试传说中的 KaiOS,随手在 GMS 上写了一段代码来测试键位。

(写这篇文章的过程中家里突然停电,还好现在的事情都是在神船上做,没有受到影响。。。。。。)

作案工具(雾)

1. 诺基亚 8110 4G

运行 Smart Feature OS(基于 KaiOS 改个名(基于被 Mozilla 放弃的 Firefox OS

(反正不管怎么样已经被我刷了 GerdaOS 了)(一个基于官方固件修改的第三方 ROM)

先过一遍配置:

SoC:Qualcomm 205

GPU:Qualcomm Adreno 304

RAM:512MB

ROM:4GB

基带:X5 LTE

LTE 等级:Cat.4

屏幕:2.4 英寸(分辨率:240*320)

SoC 具体参数(极其寒酸):https://www.qualcomm.com/products/qualcomm-205-mobile-platform

2. 神船笔记本

GX9-CT5DK,配置自行百度。

3. GameMaker: Studio

没有 GMS 2 Web 许可证,就拿 GM: S(正版,有 HTML5 许可)临时顶替一下算了。

4. Pale Moon

一个基于 Firefox 的浏览器(目前只有这个可以勉强连接我的诺基亚 8110 4G)(还是有点问题,比如运行按钮灰色)。

Firefox 52.9 ESR 貌似也可以(我试过,但没连接成功)。

Firefox 48.x 有可能成功(因为 Firefox OS 2.5 这个最后一个版本基于 Firefox 48)。

5. 其他

microUSB 数据线一条。。。。。。

开始

开始之前需要事先安装 ADB 驱动(连接过安卓机的可能都有装上),这里不再说明,没有的自行谷歌 or 百度。

使用 GM: S 新建一个项目以后,新建一个字体,名字随便只要方便写代码就行,具体字体看喜好(我很随意地使用了默认名称 font0)。

然后新建一个 Object,名字也随意,添加 Create,Step,Draw 三个事件。

Create 事件先创建一个变量:

key = "none"

Step 事件开始正式的代码,由于实在找不到 GML 自带的函数中检测键盘键位的函数,只能使用这种特别长技术含量极低的代码。

以下代码给出了测试后诺基亚 8110 4G(KaiOS)在 GM: S(以及 GMS 2)可以使用的键位。

(或许其他游戏引擎也适用)

if keyboard_check_pressed(vk_add){key="vk_add";} //No response
if keyboard_check_pressed(vk_alt){key="vk_alt";} //No response
if keyboard_check_pressed(vk_backspace){key="vk_backspace";} //Works, back key
if keyboard_check_pressed(vk_control){key="vk_control";}  //No response
if keyboard_check_pressed(vk_decimal){key="vk_decimal";}  //No response
if keyboard_check_pressed(vk_delete){key="vk_delete";}  //No response
if keyboard_check_pressed(vk_divide){key="vk_divide";}  //No response
if keyboard_check_pressed(vk_down){key="vk_down";}  //Works, down key
if keyboard_check_pressed(vk_end){key="vk_end";}  //No response
if keyboard_check_pressed(vk_enter){key="vk_enter";}  //Works, enter key
if keyboard_check_pressed(vk_escape){key="vk_escape";}  //No response
if keyboard_check_pressed(vk_f1){key="vk_f1";}  //No response
if keyboard_check_pressed(vk_f2){key="vk_f2";}  //No response
if keyboard_check_pressed(vk_f3){key="vk_f3";}  //No response
if keyboard_check_pressed(vk_f4){key="vk_f4";}  //No response
if keyboard_check_pressed(vk_f5){key="vk_f5";}  //No response
if keyboard_check_pressed(vk_f6){key="vk_f6";}  //No response
if keyboard_check_pressed(vk_f7){key="vk_f7";}  //No response
if keyboard_check_pressed(vk_f8){key="vk_f8";}  //No response
if keyboard_check_pressed(vk_f9){key="vk_f9";}  //No response
if keyboard_check_pressed(vk_f10){key="vk_f10";}  //No response
if keyboard_check_pressed(vk_f11){key="vk_f11";}  //No response
if keyboard_check_pressed(vk_f12){key="vk_f12";}  //No response
if keyboard_check_pressed(vk_home){key="vk_home";}  //No response
if keyboard_check_pressed(vk_insert){key="vk_insert";}  //No response
if keyboard_check_pressed(vk_lalt){key="vk_lalt";}  //No response
if keyboard_check_pressed(vk_lcontrol){key="vk_lcontrol";}  //No response
if keyboard_check_pressed(vk_left){key="vk_left";}  //Works, left key
if keyboard_check_pressed(vk_lshift){key="vk_lshift";}  //No response
if keyboard_check_pressed(vk_multiply){key="vk_multiply";}  //No response
if keyboard_check_pressed(vk_numpad0){key="vk_numpad0";}  //No response
if keyboard_check_pressed(vk_numpad1){key="vk_numpad1";}  //No response
if keyboard_check_pressed(vk_numpad2){key="vk_numpad2";}  //No response
if keyboard_check_pressed(vk_numpad3){key="vk_numpad3";}  //No response
if keyboard_check_pressed(vk_numpad4){key="vk_numpad4";}  //No response
if keyboard_check_pressed(vk_numpad5){key="vk_numpad5";}  //No response
if keyboard_check_pressed(vk_numpad6){key="vk_numpad6";}  //No response
if keyboard_check_pressed(vk_numpad7){key="vk_numpad7";}  //No response
if keyboard_check_pressed(vk_numpad8){key="vk_numpad8";}  //No response
if keyboard_check_pressed(vk_numpad9){key="vk_numpad9";}  //No response
if keyboard_check_pressed(vk_pagedown){key="vk_pagedown";}  //No response
if keyboard_check_pressed(vk_pageup){key="vk_pageup";}  //No response
if keyboard_check_pressed(vk_pause){key="vk_pause";}  //No response
if keyboard_check_pressed(vk_printscreen){key="vk_printscreen";}  //No response
if keyboard_check_pressed(vk_ralt){key="vk_ralt";}  //No response
if keyboard_check_pressed(vk_rcontrol){key="vk_rcontrol";}  //Works, # key
if keyboard_check_pressed(vk_right){key="vk_right";}  //Works, right key
if keyboard_check_pressed(vk_rshift){key="vk_rshift";}  //No response
if keyboard_check_pressed(vk_space){key="vk_space";}  //No response
if keyboard_check_pressed(vk_subtract){key="vk_subtract";}  //No response
if keyboard_check_pressed(vk_tab){key="vk_tab";}  //No response
if keyboard_check_pressed(vk_up){key="vk_up";}  //Works, up key

//These are all not working
if keyboard_check_pressed(ord("A")){key="A";}
if keyboard_check_pressed(ord("B")){key="B";}
if keyboard_check_pressed(ord("C")){key="C";}
if keyboard_check_pressed(ord("D")){key="D";}
if keyboard_check_pressed(ord("E")){key="E";}
if keyboard_check_pressed(ord("F")){key="F";}
if keyboard_check_pressed(ord("G")){key="G";}
if keyboard_check_pressed(ord("H")){key="H";}
if keyboard_check_pressed(ord("I")){key="I";}
if keyboard_check_pressed(ord("J")){key="J";}
if keyboard_check_pressed(ord("K")){key="K";}
if keyboard_check_pressed(ord("L")){key="L";}
if keyboard_check_pressed(ord("M")){key="M";}
if keyboard_check_pressed(ord("N")){key="N";}
if keyboard_check_pressed(ord("O")){key="O";}
if keyboard_check_pressed(ord("P")){key="P";}
if keyboard_check_pressed(ord("Q")){key="Q";}
if keyboard_check_pressed(ord("R")){key="R";}
if keyboard_check_pressed(ord("S")){key="S";}
if keyboard_check_pressed(ord("T")){key="T";}
if keyboard_check_pressed(ord("U")){key="U";}
if keyboard_check_pressed(ord("V")){key="V";}
if keyboard_check_pressed(ord("W")){key="W";}
if keyboard_check_pressed(ord("X")){key="X";}
if keyboard_check_pressed(ord("Y")){key="Y";}
if keyboard_check_pressed(ord("Z")){key="Z";}
//End
//These are all working fine
if keyboard_check_pressed(ord("1")){key="1";}
if keyboard_check_pressed(ord("2")){key="2";}
if keyboard_check_pressed(ord("3")){key="3";}
if keyboard_check_pressed(ord("4")){key="4";}
if keyboard_check_pressed(ord("5")){key="5";}
if keyboard_check_pressed(ord("6")){key="6";}
if keyboard_check_pressed(ord("7")){key="7";}
if keyboard_check_pressed(ord("8")){key="8";}
if keyboard_check_pressed(ord("9")){key="9";}
if keyboard_check_pressed(ord("0")){key="0";}
//End

Draw 事件绘制结果:

draw_set_colour(c_black);
draw_set_font(font0);
draw_text(x, y, key);

之后就可以新建一个 room 了,还记得诺基亚 8110 4G 的分辨率吗?为了尽量降低消耗这里把房间分辨率设置成与诺基亚 8110 4G 相同。

再把之前的 Object 随便找个地方放就可以导出了,记得导出平台选择 HTML5 。

编译可安装包

导出完成后的文件应该是这样的。(本来还有个 favicon.ico 但这里用不上被我删掉了)

接下来打开 Pale Moon 找出 WebIDE,新建一个应用,名字随便:

然后基本项目结构有了:

删掉里面的 app.jsindex.html 后替换成导出后的文件(包括那个文件夹)

manifest.webapp 中补全信息后添加全屏模式:

"fullscreen":"true"

完整配置文件如下:

{
  "name": "gmstudiotest",
  "description": "A Hello World app",
  "launch_path": "/index.html",
  "fullscreen":"true",
  "icons": {
    "16": "/icons/icon16x16.png",
    "48": "/icons/icon48x48.png",
    "60": "/icons/icon60x60.png",
    "128": "/icons/icon128x128.png"
  },
  "developer": {
    "name": "Your name",
    "url": "http://example.com"
  }
}

保存完毕后就可以连接手机点击那个运行按钮测试啦。

特殊情况(如无请无视)

不过不知道是环境原因还是系统原因,无论我怎么修改,WebIDE 的运行按钮一直是灰色的无法点击。。。。。。

于是只能将游戏打包为 zip 后使用 GerdaPkg 或 OmniSD 安装,但安装这其中之一之前均需获取 root 权限,其中 GerdaPkg 需要像我一样刷 GerdaOS,具体可以谷歌搜索(国际通用)或浏览这个博客(中文):http://www.heppy.wang/

由于单纯使用 7z 打包怎么都不行,于是研究了自带游戏贪吃蛇的目录结构,然后目录结构就变成了这样。。。。。。

首先将项目文件夹更名为 application(我不确定使用其他名字是否有效)后新建一个文件夹(随意,英文即可,这里使用 gmstudio_in_kaios)将项目移动到这里,同时新建一个文件夹,同样名字随意,英文即可,这里写成 target 比较容易识别。

之后在这个文件夹里新建一个 metadata.json 文件,内容如下:

{
    "version": 1,
    "manifestURL": "app://e585bc19-face-4c1f-adcb-071bdd4093d7/manifest.webapp"
}

其中 "version" 为版本号,可随意,"manifestURL" 为创建项目于时 WebIDE 提供的应用 ID,填入该 ID 即可。

回到上一级文件夹,新建一个 Batch 批处理,使用 7z 命令行模式打包,其中文件夹需按个人命名修改,也可以不使用 7z 来打包,只要可以正常安装就行:

del ".\target\application.zip"
"C:\Program Files\7-Zip\7z.exe" a -tzip application.zip ".\application\*"
move "application.zip" "target"
"C:\Program Files\7-Zip\7z.exe" a -tzip gmstudio_in_kaios.zip ".\target\*"
pause

安装

以下仅适用于安装有 GerdaPkg(已集成到 GerdaOS 的文件器中)或 OmniSD,有正规的 WebIDE 方式的可以忽略。

运行上面的批处理脚本后获得 gmstudio_in_kaios.zip,将手机开启 USB 存储器后通过 USB 接入电脑,把这个压缩包放入 downloads 文件夹。

最后使用 GerdaPkg 或 OmniSD 安装即可。

运行截图

先解释几个问题

  1. 为什么不使用录屏/投屏?
    尽管 KaiOS(Firefox OS)使用了 Android 6.0.1 的部分代码,但 KaiOS 并不是完整的 Android,所以有些功能会因为系统崩溃或缺少相关文件导致无法使用,所以这里只能放几个截图了。。。。。。尽管在测试中发现 screenrecord 命令存在,但执行后疑似因编码器问题导致录屏失败且导致系统崩溃重启。

    尝试使用 scrcpy(Genymotion 开发的开源投屏工具)发现 KaiOS 方缺少相关文件从而导致无法使用。

Demo

https://github.com/LiarOnce/gmstudio-keytest-kaios