據Bmob官方人員的透露,他們一開始產生作Game SDK的念頭,主要就是由於吃雞的火爆。java
(還有一大緣由是,從後臺數據、客服與開發者一對一聊天獲取的信息來看,使用Bmob目前服務的開發者中,須要遊戲實時數據雲服務的開發者佔了很大的比例。)算法
因此一開始Bmob團隊開發Game SDK和Demo的時候,都是復刻 藍洞的絕地求生
這款遊戲,努力在還原全部這個正版遊戲的設定。後來歷經滄桑,開發到遊戲 能跑了 ,微信小遊戲
又出來了,而小遊戲須要實時傳輸數據 僅支持Web socket ,且不少人都看好在這個小遊戲平臺開發的休閒類、益智類、棋牌類等等輕量的遊戲。這樣一來,之前面基於 FPS
開發的、 強交互
的、高頻處理數據
的雲服務就不適用了。數據庫
因而Bmob團隊把這一套服務 幾乎徹底推倒重來,把核心算法保留下來後,再借鑑衆多遊戲的思路(其實就是主程沉迷過的遊戲),解剖各種型遊戲的各類場景,從新開發了一套BGS系統(心疼前面那一套花掉的血與淚一秒鐘)。如下以 《夢幻西遊》、《絕地求生》 遊戲爲小節,分析一下如何用BGS實現。安全
(筆者只是Unity開發萌新一枚,非專業遊戲行業人士,若有錯誤,還望諒解)服務器
這個遊戲真是讓人又愛又恨啊,想當年...微信
好吧咱們仍是從技術層面來討論一下。網絡
首先,這絕對是一個是 很是依賴數據庫
的網遊,小到物品欄的擺放、刷塔得到經驗,大到人物升級、任務完成,都是創建在數據庫操做完成的基礎上才容許客戶端呈現的;
也就是說,在你網絡很差的狀況下,連物品欄你都調整不了擺放的次序,選中的東西會沒掉,且不會移動到你指定的地方。若是你要說,這不是廢話嗎?哪一個遊戲不是很是依賴數據庫?那你就錯了,不少實時對戰的遊戲還真不須要,例如FPS,只要在戰鬥開始時獲取一下玩家姓名和皮膚,戰鬥結束時記錄一下戰績就能夠了socket
其次,全部玩家動做都以 服務器的計算
爲準,例如玩家走路,在必定的幀數內你能走幾步,都是服務器計算的;此外在戰鬥中,傷害的計算、經驗的結算,都是由服務器計算的;挖寶圖的時候,爆率都是服務器調整的;
也就是說,在你網絡很差的狀況下,連走路你都走不了,就算在客戶端來看你邁出了幾步,可是網絡一恢復,你原來在哪仍是在哪。若是你要說,這不是廢話嗎?哪一個遊戲不是全經過服務器來計算?那你就錯了,不少實時對戰的遊戲還真不須要,例如FPS,玩家的位置在哪裏、是否擊中目標對其它玩家形成傷害,都是客戶端本身說了算的,由於不少服務器沒有內置整套的物理引擎,即便有,形成的服務器消耗太大,成本也過高(試想一下,在PUBG巔峯300w玩家同時在線的時候,可能有6w個房間,每一個房間都要有一套物理引擎,一局聽說有10萬+顆子彈,每一顆子彈飛出去都須要有彈道下墜,要逐幀計算初速度和重力加速度,以及和整個地圖海量的3D剛體進行碰撞檢測)。這也是爲何PUBG有飛毛腿、隔山打牛、瞬移、神羅天徵、萬象天引等等外掛了函數
最後,除去IM系統來說,實時數據方面,主要是每一個城鎮的其它玩家分佈的位置,而夢幻西遊一個城鎮掛機的玩家是很是多的,因此開發的時候,確定是將每一個(有移動行爲的)玩家的位置同步到界面可視範圍內的其它玩家那裏,而不是推送給整個城鎮的玩家;即使如此,在有活動的時候,同屏的玩家仍然是很是多,這個時候就會感受什麼操做都特別卡。也就是說,在你網絡很差的狀況下,哪怕你身邊人山人海,你也可能一我的都看不到,而你在荒無人煙的野外跑商的時候,連聊天都比較流暢
若是你要說,這不是廢話嗎?哪一個遊戲不是隻傳遞可視範圍內其它玩家的信息?那你就錯了,不少實時對戰的遊戲還真不能夠,例如FPS,你朝遠方、朝天邊隨便開一槍,也可能射死個幾公里之外、無需渲染的玩家,這也是爲何透視外掛再遠可以看到全部玩家的信息。spa
那麼,如何使用 Bmob Game SDK
來實現像 夢幻西遊
這樣的一款網遊呢?
首先,所有同區的玩家都在同一個Room,這個Room不須要同步任何玩家眷性
其次,必定要用 Bmob Game SDK
的 雲端代碼
,裏面 自帶
了 Bmob數據庫
的操做接口,能夠快速結合數據庫實現不少功能
最後,必定要充分利用 Bmob Game SDK
的 雲端代碼
,用屬性監控、事件監控等功能,能夠完美實現上面所說的幾個特性,例如傷害計算、同屏推送等
歡迎四排組隊,本人亞服排名3w求大腿...
好吧咱們仍是從技術層面來討論一下。
我以爲比較有意思的討論點在於:
FPS類,或者說全部有PVP模式的遊戲,都有一個共同的煩惱,就是Damage誰來斷定的問題;選項無外乎三個:攻擊者
、被攻擊者
和 服務器
首先,咱們排除掉單純採信 被攻擊者
斷定傷害這個選項,雖然這種方式在某些場合下顯得較爲公平(玩家被攻擊得明明白白,不會莫名其妙GG);可是這樣很容易形成 高Ping大神
和 鎖血掛
的出現;並且這樣的話,掉線的玩家就永遠不會受傷和死亡了。
所謂高Ping大神,就是將本身的網絡搞差,例如利用南轅北轍的加速器,或者自己就是"卡B",他們能夠在敵人的千軍萬馬中幾進幾齣,毫髮無傷;說極端一點,拔掉網線,就能夠進入無敵狀態,還附送大招CD恢復
鎖血掛的實現原理有不少種,有一種就是篡改本地邏輯或攔截網包,以破壞上報本身受傷的信息,服務器永遠不知道客戶端受到了傷害,在其它玩家看來就至關於鎖血了。
其次,咱們也要排除掉單純採信 攻擊者
斷定的方式,雖然目前大多數FPS遊戲都是這樣實現的,可是隔山打牛你見過嗎?回放時看到神仙對着空氣來一發噴子方圓公里寸草不生的恐懼你忘了嗎?
所謂隔山打牛,其實就是利用了子彈與其它玩家的碰撞檢測時發送信息給服務器這一點,若是hook了這個函數,或者破解了這個信息的網包協議,隨便開一槍均可以將子彈精準得"碰撞"到對方頭上,由於服務器傻啊
而後,還要排除單純使用 服務器
斷定的方式,由於這是一個對現實世界還原度很高的FPS遊戲,不是LOL、農藥那種MOBA遊戲,也不是夢幻西遊那樣的回合制遊戲。要完成模擬子彈的射出的話要求服務器有一套和客戶端徹底同步的物理引擎(沒有渲染功能),消耗太大;此外,在玩家須要爆頭擊殺、遠程點殺的時候,稍微一點的角度誤差也會影響最終的結果,這意味着即便是即使有足夠的資源支撐服務器模擬3D世界,高Ping玩家也可能由於那一點點角度,永遠都能擊中但殺不死那個敵人。而PUBG的彈道下墜更是讓服務器模擬起來更加吃力,畢竟不像某go是激光槍啊。
雖然上面已經講過了,但這裏爲了字數再囉嗦一遍:
PUBG的玩家同時在線巔峯值是300萬
假如每一個房間有50我的(不要說100人,有不少房間在決賽圈呢)
就會有有6萬個房間正在進行遊戲
每一個房間都要有一套物理引擎
每一顆子彈飛出去都須要有彈道下墜,這意味着要逐幀計算初速度和重力加速度,來肯定子彈位置
子彈飛出去後,要逐幀和整個地圖海量的3D剛體進行碰撞檢測
Uzi射速是0.048s/發
據分析源碼的人說一局聽說有10萬+顆子彈
因此,我認爲最好的斷定方式是 攻擊者
結合 服務器
斷定的方式,攻擊者上報了擊中事件後,服務器計算這個上報信息是否可信,而後再作出最終斷定
服務器判斷可信度的方式有不少,等級也分不少種:
以目前的BGS內測的狀況來看,作到 攻擊者
結合 服務器
斷定,而且加上 中層次的判斷
是徹底沒問題的:
要求開發者寫雲端代碼,在雲端代碼添加 Position
和 Rotation
的 BmobGameHook
,在上報玩家擊中事件時,用 java.lang.Math
裏面的三角函數就能夠簡單判斷一下此次擊殺是否合理了
安全區確定是服務器統一肯定的,而且是逐幀計算的
隨機圈的時候:
縮圈的時候:
其中m = (大圈半徑 - 小圈半徑) / 幀數
其中n = [(大圈圓心x - 小圈圓心x) / 幀數, (大圈圓心y - 小圈圓心y) / 幀數]
這一套徹底能夠用Bmob Game SDK的雲端代碼的 Room.onTick
實現,而後再逐幀向客戶端下發當前的安全區的圓心和半徑,而且結合 Player.getPosition
,計算玩家是否在圈內,若是在圈外的,調用 Player.setHp
進行減血
請注意,上面提到的 getPosition、getRotation、onAction_Damage、setHp (還有相似 onUpdate_Posision)等方法,都不是Bmob Game SDK雲端代碼自帶的!而是開發者在設定了他遊戲有hp這個屬性後,在上傳的 Player.java 類內,直接按這種命名規則寫這個方法就能夠讀取、監聽、修改這些屬性啦,超方便的!
有什麼好的建議,給我留言,或者直接去Bmob遊戲開發官方羣中呼喚我:
Q羣:726133616