黑手党在Go,Vanila JS和WebSocket'ah



这将与流行的纸牌游戏“ 黑手党 ”的网络实现有关。 它是为娱乐和游戏开发经验而编写的。 第一个版本是在两周的空闲时间里编写的,同时又被重写为第二个版本。 这个游戏的优势是没有主机。

根据开发目标,我决定了功能的实现/不实现。
到底需要做什么:

  • 重复经典游戏规则的最小游戏
  • 领导者在客户端设备上的命令声音
  • 即使重新启动浏览器选项卡后仍继续游戏

未计划或可以推迟的时间:

  • 游戏注册
  • 管理界面
  • 将游戏数据永久存储在数据库中
  • 设备之间的时间同步

后端


https://github.com/mrsuh/mafia-backend
用Go语言编写。 它存储游戏状态并负责其逻辑。

在游戏过程中,您可以联系服务器以查找完整信息:

curl 'http://127.0.0.1:8000/info?game=23' | python -m json.tool 

游戏信息显示
{
"event": "greet_mafia",
"event_status": 2,
"id": 23,
"is_over": false,
"iter": 1,
"players": [
{
"addr": "172.18.0.1:51438",
"createdAt": "2018-09-23T14:39:29.631475779Z",
"id": 33309,
"name": "Anton",
"role": 4
},
{
"addr": "172.18.0.1:51440",
"createdAt": "2018-09-23T14:39:32.867080927Z",
"id": 5457,
"name": "username:0",
"role": 2
},
{
"addr": "172.18.0.1:51442",
"createdAt": "2018-09-23T14:39:32.882463945Z",
"id": 14214,
"name": "username:2",
"role": 1
},
{
"addr": "172.18.0.1:51444",
"createdAt": "2018-09-23T14:39:32.895209072Z",
"id": 63759,
"name": "username:1",
"role": 3
}
],
"win": 0
}


或找出服务器的状态:

 curl 'http://127.0.0.1:8000/health' | python -m json.tool 

显示服务器状态信息
{
"runtime.MemStats.Alloc": 764752,
"runtime.MemStats.NumGC": 0,
"runtime.MemStats.Sys": 4165632,
"runtime.MemStats.TotalAlloc": 764752,
"runtime.NumGoroutine": 14
}


为了确定播放器是否仍处于活动状态,后端将发送心跳。 如果玩家在一定间隔后没有响应,则将其从游戏中淘汰。 同时,如果玩家在间隔时间结束之前重新连接(网络已消失),则他可以继续游戏。

为了稳定运行,后端使用标准Go库进行单元测试,在其中检查主要操作方案。

 go test mafia-backend/src -cover ok mafia-backend/src 1.315s coverage: 70.7% of statements 

前端


https://github.com/mrsuh/mafia-frontend
它是用纯JS编写的,并使用Grunt构建。
它没有任何逻辑。

后端发生事件时,它将呈现所需的页面,显示发送给它的数据,并播放新事件的声音。

前端将游戏和玩家ID存储在LocalStorage或浏览器查询字符串中(如果您需要在一个浏览器中为不同的玩家运行多个选项卡)。 完全缺乏逻辑以及游戏基本参数的存储使得即使在重新加载页面后仍可以恢复游戏状态成为可能。

浏览器禁止在没有用户干预(例如,按下按钮)的情况下自动播放声音。 为了为后端附带的每个事件播放声音,仅制作了1个JavaScript Audio对象。 每个玩家必须按下一个按钮才能开始游戏,然后音频对象变为活动状态(可用于播放),随后他可以更改src参数以播放不同的声音而无需用户干预。

另外,为了测试游戏,编写了一个可以自己玩的“机器人”。
只需打开浏览器选项卡,其中的参数表明您要运行测试

 http://127.0.0.1?master=1&test=1&sound=0&testUsersCount=5 

并允许通过JavaScript打开该域的新标签页。
游戏开始后,将打开另外5个带有玩家的选项卡,他们将开始在彼此之间玩耍。

交互协议


选择WebSocket协议是因为需要在后端和前端之间进行持续的双向数据交换,并且需要两种语言的支持。

游戏活动


整个游戏分为几个事件:

大事记
  • 游戏
    • 创造
    • 参加
    • 开始
    • 超过
    • 重新连接


    • 开始

  • 晚上
    • 开始

  • 市民问候
    • 开始
    • 角色
    • 结束

  • 黑手党问候
    • 开始
    • 玩家们
    • 结束

  • 法院
    • 开始
    • 玩家们
    • 结束

  • 黑手党
    • 开始
    • 玩家们
    • 结束

  • 医生
    • 开始
    • 玩家们
    • 结束

  • 女孩
    • 开始
    • 玩家们
    • 结束

  • 谢里夫
    • 开始
    • 玩家们
    • 结束



事件具有开始,结束和内容。
在活动开始和结束时,将向所有活动玩家发送通知,必须进行确认。 仅在所有活动玩家确认此事件之后,游戏才继续(例如,仅在播放声音文件之后)。

码头工人


整个游戏可以使用Docker进行
docker-compose.yml

 version: '3' services: mafia-frontend: image: mrsuh/mafia-frontend:latest container_name: mafia_frontend ports: - 9080:80 mafia-backend: image: mrsuh/mafia-backend:latest container_name: mafia_backend ports: - 8000:8000 

安装Docker就足够了(如果尚未安装),复制文本docker-compose.yml并运行以下命令:

 docker-compose up 

之后,您可以在浏览器中打开游戏选项卡:

 http://127.0.0.1:9080 

结论


在这里,您可以看到结果(回放速度提高了1.5倍)。


在我将近一个月的空闲时间进行开发之后,我得到了一款非常稳定的游戏,可以与朋友一起玩。 游戏可以承受页面重新加载或临时网络中断。 尽管没有时间同步,但事件在设备上的语音处理仍然有效。 没有计划进一步开发游戏。

PS:感谢Lera为游戏配音。

Source: https://habr.com/ru/post/zh-CN423821/


All Articles