彈幕互動游戲開發(fā)教程(心得?)
保護環(huán)境從我做起,大家好,我是魔方12139。
這篇文章是我在彈幕互動游戲開發(fā)過程中的心得和感想記錄,有一些教學(xué)內(nèi)容,不能確保高可靠性,請讀者朋友們謹(jǐn)慎參考。
所謂的彈幕互動游戲,即是指在直播時,觀眾可以用彈幕來操作的游戲。常規(guī)游戲的操作者只有玩家,而彈幕互動游戲的操作者還有愿意參與的觀眾。
毫無疑問,彈幕互動游戲的技術(shù)基礎(chǔ)和核心是彈幕消息的獲取和處理。通常情況下,看彈幕的都是觀眾,且彈幕消息都顯示在網(wǎng)頁或者手機應(yīng)用界面上,和游戲程序無關(guān)。不過,借助某些技術(shù),可以用自己的程序獲取并處理彈幕,從而實現(xiàn)用彈幕操作游戲。
WebSocket
以下內(nèi)容摘自RUNOOB:
WebSocket 是 HTML5 開始提供的一種在單個 TCP 連接上進行全雙工通訊的協(xié)議。
WebSocket 使得客戶端和服務(wù)器之間的數(shù)據(jù)交換變得更加簡單,允許服務(wù)端主動向客戶端推送數(shù)據(jù)。在 WebSocket API 中,瀏覽器和服務(wù)器只需要完成一次握手,兩者之間就直接可以創(chuàng)建持久性的連接,并進行雙向數(shù)據(jù)傳輸。
在 WebSocket API 中,瀏覽器和服務(wù)器只需要做一個握手的動作,然后,瀏覽器和服務(wù)器之間就形成了一條快速通道。兩者之間就直接可以數(shù)據(jù)互相傳送。
HTML5 定義的 WebSocket 協(xié)議,能更好的節(jié)省服務(wù)器資源和帶寬,并且能夠更實時地進行通訊。
簡單來說WebSocket就是一個【服務(wù)器往我這兒發(fā)東西的通道】。
B站直播的彈幕信息就是通過WebSocket進行傳輸?shù)?。知道了這一點,只需要用一個WebSocket和B站發(fā)送信息的端口建立連接,就能收到發(fā)來的彈幕信息,然后再進行處理了。
HTML5提供了這個協(xié)議,那就用HTML+JavaScript編一段程序來看看。
創(chuàng)建index.html文件,用文本編輯程序打開,輸入如下內(nèi)容:
以上HTML文檔創(chuàng)建了一個空頁面,并在其中運行一個腳本。這個腳本創(chuàng)建一個WebSocket,與地址wss://broadcastlv.chat.bilibili.com:2245/sub建立連接(wss前綴表明這是一個WebSocket地址)。
當(dāng)連接建立時,它發(fā)送一段信息。其中包含兩部分:
第一部分是信息頭。
第二部分是信息體。這部分中比較重要的是要連接的直播間號。在電腦端上用瀏覽器隨便打開一個直播間,可以在地址欄中看到如下內(nèi)容:

紅框部分"22908468"就是直播間號。
在彈幕互動游戲中,要連接的直播間號當(dāng)然是自己的。如果要更改,修改對象data的屬性roomid的值即可。
初始信息發(fā)送后,它啟動一個循環(huán)計時器,每隔30000毫秒,也就是30秒,發(fā)送一次心跳信息。這是一種B站直播時使用的協(xié)議,需要每隔30秒發(fā)送一次,否則會認(rèn)為連接斷開。
當(dāng)收到信息時,它把收到的信息打印到控制臺上,暫時不做其他事。
用瀏覽器打開index.html,按F12打開開發(fā)人員工具,轉(zhuǎn)到Console(控制臺)選項卡,觀察輸出。輸出如下:

看不懂,不過能收到東西就表明這是成功的第一步。
為了避免混淆,把JavaScript代碼單獨存在其他文件里。在index.html所在目錄中創(chuàng)建文件index.js,把index.html中<script>標(biāo)簽中的所有東西都剪切到index.js中,保存。修改<script>標(biāo)簽如下:
這代表它執(zhí)行的js腳本來自index.js文件。
接下來重點處理WebSocket收到的信息。收到的信息分為若干段,每段由兩部分組成。
第一部分是信息頭。其中有用的信息主要是第二部分的長度和消息類型。
第二部分是信息體。彈幕互動游戲需要的彈幕信息就在這部分中。
信息體在傳輸中會被壓縮,需要解壓才能恢復(fù)成正常信息。解壓所需的程序代碼太多了,我在這里寫不下,大家可以去這個地址下載:
https://raw.githubusercontent.com/mcube-12139/danmaku-game/main/pako.js
復(fù)制所有內(nèi)容,存為文件pako.js,放在工作目錄(即index.html所在目錄)下,在index.js的<script>標(biāo)簽之前添加一個<script>標(biāo)簽,執(zhí)行pako.js,這樣就能在后面的index.js中使用其中的東西了。
修改index.js中消息接收部分。逐段處理消息,對其中的信息體進行解壓并打印到控制臺。
刷新頁面重新載入index.html,觀察控制臺。
如果此時指定的直播間中有觀眾發(fā)送彈幕,可觀察到輸出如下:

是一些可讀的JSON文本。
信息體的類型主要包括彈幕、禮物、通知、人氣刷新等,在彈幕互動游戲中需要進一步判斷類型,如果是彈幕再做后續(xù)處理。對收到的JSON文本進行解析,如果鍵"cmd"的值是"DANMU_MSG",那就表明這是彈幕信息。彈幕內(nèi)容在info數(shù)組中,其中info[1]是彈幕內(nèi)容,而info[2]則是彈幕發(fā)送者的相關(guān)信息。據(jù)此修改index.js如下:
只把彈幕信息打印到控制臺。刷新,觀察輸出:


這樣我們就完成了從直播間抓取彈幕的全部操作。只要把收到的彈幕消息與游戲邏輯進行連接,就實現(xiàn)了彈幕互動游戲。
大家可以從GitHub找到我之前開發(fā)的彈幕互動掃雷和數(shù)獨游戲的全部源碼,如果有我沒有說清的東西也可以進行下載和進一步閱讀。地址如下:
https://github.com/mcube-12139/danmaku-game
鳴謝
Bilibili UP主紅色xyz(322954448)。本文所述大部分內(nèi)容來自他的專欄:B站直播彈幕禮物采集器。
EOF