如何用B站弹幕控制游戏
大家好,我卡颂。
中秋节在家无聊,想整点儿好玩的。思来想去决定做个用弹幕控制的坦克大战。
文章图片
具体逻辑是:
- 监听直播间水友们的弹幕
- 将弹幕中有效的指令提取出来
- 将指令转化为键盘按键在
坦克大战
中输入 - 直播
坦克大战
游戏画面
操作
到展示
的完整逻辑,所有直播间的水友都可以参与游戏,下面是实际效果:让我们来看看技术细节吧。
监听水友们的弹幕 这一步我使用
puppeteer
监听我直播间的DOMNodeInserted
事件。
DOMNodeInserted
事件在一个节点作为子节点被插入到另一个节点中时触发
当触发后,根据类名筛选出属于弹幕的节点。不得不说,B站弹幕数据真的很好抓,都存在
$('.chat-item.danmaku-item').dataset()
中了。文章图片
指令识别 抓取出弹幕内容后,需要些额外处理,比如:
- 12345代表上下左右 开炮,需要识别出带这些数字的弹幕
- 奇数昵称长度的水友的弹幕控制玩家1的坦克,偶数控制玩家2的坦克
- 处理同一时间多人发弹幕的情况
200ms到期后出现次数最多的指令作为最终指令。
文章图片
魔改坦克大战 接下来我开始寻找开源的坦克大战,这个仓库的
star
最多:battle-city开始我以为作者是用
canvas
实现的游戏,但是当我看到这些文件名时,就知道事情没有这么简单:文章图片
整个游戏居然都是
React
做的!文章图片
子弹是
React
组件,场景切换是路由切换,状态管理用的Redux-Saga
。【如何用B站弹幕控制游戏】不得不说,这个项目写下来,
Redux-Saga
这套状态管理方案作者肯定是玩儿明白了。文章图片
项目间通信 为了将B站弹幕抓取项目中识别的指令实时传递给坦克大战,需要使用
websocket
协议。这里我选择的是
socket.io
库。值得一提的是:需要在服务端(也就是弹幕抓取项目)的在坦克大战中,接收到的指令构造成键盘事件派发出去:socket.io
配置中设置cors: true
解决跨域问题。
const fireKeyEvent = (evtType: string, keyChar: string) => {
var KeyboardEventInit = {key: keyChar, code: keyChar, location:0, repeat:false, isComposing:false};
var evtObj = new KeyboardEvent(evtType, KeyboardEventInit);
document.dispatchEvent(evtObj);
}
总结 整个过程没有什么技术难点。唯一比较坑的是:直播有5秒左右延时,所以从弹幕发出到操作坦克有延迟。
在5秒延迟的情况下,本来弱智的电脑,简直天神下凡。
为了减少玩家的挫败感,我决定,让玩家互相对决。
文章图片
这样,大家都在同一起跑线上啦。
文章图片
最后,在一片弹幕中,渡过了一个祥和的中秋节夜晚。
我不是说直播间的各位水友,我说我自己,真够无聊的......
文章图片
欢迎加入人类高质量前端框架研究群,带飞
推荐阅读
- 任时光绽放成六月繁花
- 我从来不做坏事
- 考研英语阅读终极解决方案——阅读理解如何巧拿高分
- 樱花雨
- 如何寻找情感问答App的分析切入点
- 拍照一年啦,如果你想了解我,那就请先看看这篇文章
- mybatisplus如何在xml的连表查询中使用queryWrapper
- MybatisPlus使用queryWrapper如何实现复杂查询
- 人如果没梦想,和咸鱼有什么区别(自媒体时代把握住就能咸鱼翻身)
- 如何在Mac中的文件选择框中打开系统隐藏文件夹