创作背景

–“你综评得需要个项目设计,你上网搜一个吧”
–“为什么要搜,我这么多项目,自己随便挑一个写一个不就行了”

背景

AmongUS(我们之中,又译作太空狼人杀)是一款考验玩家推理能力和细节感知力的益智游戏,游戏背景设置于太空、天空基地、蘑菇岛、飞船或形似火星的虚构星球表面,玩家将扮演船员(Crewmate)或内鬼(Impostor)之一。船员的目标是找出内鬼或完成任务,而内鬼的目标是杀死所有船员或让他们全部被投出局且不被识穿身份。

AmongUS发行至今,玩家已经上亿,并持续推出了五个地图,诸多玩家在享受着游戏的同时锻炼着自己的思维。

受到AmongUS的启发,爱写程序的我不禁萌生了一个想法----写一个真人版AmongUS。

目的与意义

将AmongUS的游戏内容搬到线下实现,让玩家同其他线下同伴一起享受猜疑与推理的魅力。同时锻炼自己的编码能力。

实现过程

Step 1: 考虑实现所用的技术栈

首先明确AmongUS的核心是地图,所有玩家都在地图上活动。而真人AmongUS(后简称RealAU)也需要一张地图,这张地图不是虚拟的地图,而是真实存在的地方。

要使用地图,并获取玩家定位,我们首先就可以想到使用已经成熟的库。生活中,我们使用最多的地图软件应该就是”高德地图”了,前往高德开放平台,我们可以看到高德提供的API和SDK(如下图1)。

图1

结合我们熟悉的技术栈,初步选定使用Android定位SDK+JS API实现。

Step 2: 初步构想

我个人更加熟练前后端开发,因此起初的构想是直接使用网页实现,调用高德JSAPI。

同时为了进行多人游戏,使用我之前的Socket中转服务器项目,来进行多设备无公网IP之间的通信。

Step 3: 初步实现&验证可行性

有了构想,我们接下来进行初步的实现,来验证该想法的可行性。

新建一个静态页面,我选用MDUI作为前端组件库,使用AMap渲染地图,并加载Geolocation组件通过浏览器获取精确定位,具体实现过程不详细描述。

初步实现效果如图2所示

图2

可以看到实际定位效果并不好,实际定位精度可能甚至能达到一公里。如果使用代理的话甚至定位会偏离到代理服务器所在位置。证明使用纯前端来写,效果不好,根本无法进行游戏。

Step 4: 更换实现途径&进行实现

既然浏览器定位精度不高,我们只剩下了一条选择:使用Android定位SDK或iOS定位SDK进行定位。之所以我一开始不选择这条路径进行实现,是因为我并不熟悉Android开发,安卓开发对我来说是一个完全陌生的领域,可能需要长时间的学习才能入手。因此我们考虑用Android应用获取定位后通过地址哈希值传递给网页,这样的话我们可以先实现前端网页,将Android客户端的工程往后放一放。

我们通过地址哈希传递lng和lat经纬度参数,JS自己写一个类实现对哈希值的操作(如图三,截取了部分内容)

图3

该类实现了增、删、改、查以及监听操作。

非常好,再调用AMap的接口绘制出坐标点(如图4)

图4

这样我们就初步实现了当前玩家位置的显示。

Step 5: 完善地图相关

AmongUS地图还有几个要素:任务点、其他玩家和边界。那么我们调用AMap的相关接口,实现地图边界(Polygon绘制),任务点(CircleMarker)和其他玩家(CircleMarker)。同时再编写一个CtUI类,封装对这些对象的控制。

图5 最终效果

(注:图中蓝点表示玩家当前位置,大的蓝色圈表示玩家的视野范围,绿色点表示任务点,红色点即为其他玩家所处位置。值得注意的是,当其他玩家的位置离开当前玩家的视野范围(大蓝圈)之后,其他玩家的红点就会自动消失;当当前玩家离开红色边界所表示的范围时,就会提示离开边界。详见下面的录屏)

Step 6: 实现消息传递

AmongUS中,玩家通过文字聊天进行沟通,我们也要实现类似的功能。

通过上文提到的Socket中转服务器,JS调用自己封装的SocketClient库连接并监听消息。(如图6)

图6

图7

由图7可以看到实现效果(左下角)。

那么进一步完善,我们写出更多多人交互内容,如投票、刀人、报告尸体还有等待页面等。

图8 等待玩家页面实现效果

Step 7: 完善外围功能

游戏主体功能基本都完成了,接下来我们就需要完善外围功能。

首先,我们要有用户系统,这里我们可以接入我之前的项目(采用OAuth2标准)

图9 登录页面

其次,我们要允许用户创建房间,允许用户自行编辑地图、添加任务点以及更改房间设置。这一步涉及到后端数据库交互,我们先设计数据表:(如图10)

图10

然后路由中绑定地址(如图11),具体逻辑在IndexController中实现。

图11

实现效果如图所示:

图图
图图

Step 8: Android客户端实现

接下来开始最艰难的一部分。我们首先部署好Android开发环境,创建一个包含空Activity的项目。

然后利用我们其他技术栈的开发经验,编辑一个视图,添加ProgressBar和WebView。

图12

随后查阅文档等,初步写出程序(请求权限、初始化WebView等)。

图13 初始化WebView部分代码
图14

查阅高德文档,写出定位相关的内容;随后再引入Volley和FastJson库,写一个自动检查更新的功能。最终实现效果如(图14)。

Step 9: 整体完善&优化&完工

最终花点时间打磨一下我们的整体项目,比如写一个介绍页面和发行版列表等(如图15、16)

图15 介绍页面
图16 发行版下载

然后就正式完工啦!

成果展示

该项目已经上线,目前还在试游玩中……

您可以访问 https://rau.xzynb.top 体验游戏。

五、个人收获

通过这个项目,我收获了许多:我入门了Android开发并写出了自己的第一个真正意义上的Android应用程序作为RealAU客户端;我掌握了AMap高德地图JS
API的用法,地图相关的操作对我来说也不再是头疼的难事;这也是我第一次从零开始进行中型游戏的开发,其中一些解决问题的思维方式也令我受益终生;同时也积累了大量开发经验,为以后的开发铺垫了厚实基础。

尽管本项目消耗了我一个寒假多的时间进行开发,但是成功后收获的成就感和喜悦感也是沉甸甸的,未来我一定会继续练习自己的能力,进行更加复杂的开发,接触更多的技术栈!