沙盒、無縫地圖設計(個人想法,草稿)

沙盒、無縫地圖設計(個人想法,草稿)

 

一、簡介

MMO(大型多人在線遊戲)無縫地圖設計。主要目的解決目前手遊通用的分線策略和地圖安場景分割,提升單地圖人數的承載量,實現資源消耗低動態分割 。主要針對服務器無縫地圖處理及服務器搭建,涉及地圖切分、線程模型分配,navmesh尋路處理,戰鬥設計,數據存儲模型。待補充方案,服務器碰撞物理引擎,AI,網絡通信,沙盒同步。 涉及技術:

1. 四叉樹進行地圖區域動態分割管理

2.九宮格進行空間對象同步管理

3.navmesh和A*算法進行尋路查找

4.netty的EventLoop線程模型實現地圖區域消息順序處理

 

二、地圖切分

1.四叉樹地圖分割

地圖(MapInfo)長度以米爲單位,使整個長度爲2的n次方(爲使地圖、區域和九宮格同步格子在唯一包含在某個對象內,區域最小單元爲一個九宮格,最大單元則爲整個地圖)。如4096*4096的地圖。一個地圖對應多個區域(AreaInfo),一個區域分配一個線程隊列(EventLoop,獨佔線程),即區域爲地圖管理執行的基本單元。區域長度爲2的n次方,如512*512 地圖同步九宮格爲也爲2的n次方,如32*32。大小關係如下圖所示:

 

AreaInfo擴張:

a、首先使用四叉樹將地圖分割成等分的四個區域,假設以每個四叉樹單元最大承載1000同步對象運算,左上區域超過爲2000人,其他區域BCD都各自少於1000人,則將BCD區域分別設爲AreaInfo和線程隊列。 添加編號1、2、3、4。

b、將左上區域再進行四叉樹分割,編號爲5、6、7、8,如果EFG區域同步對象少於1000,則爲之分配AreaInfo和現場隊列。 如果左上仍然大於1000個同步對象,使用四叉樹再進行分割,直到當前區域同步對象小於1000。假設9、10、11、12已是最後的分配區域

 

AreaInfo收縮:

a、當地圖9、10、11、12內的總同步對象少於600人時(60%爲閥值),則取EFG的共同父對象作爲執行AreaInfo(綁定線程隊列),9,10,11,12區域的消息全部放到父AreaInfo隊列中執行

b、當9、10、11、12的父對象任然不到600人時,執行步驟A,直到最大值

 

2.邊界數據同步處理

如下圖所示,當玩家處於區域(AreaInfo)邊界同步區域時,需要和其他區域的玩家互相看見並交換。如圖中有四個區域,ABCD,當玩家所在格子1時需要分別看見再BCD區域的234格子中的對象,因此需要將234格子中的對象同步複製到A區域,反之亦然。

因爲1,2,3,4所在區域在不同的線程處理,因此存在併發型問題,因此1和2中的對象處理邏輯需要實現線程安全處理,數據修改放在各自的線程中處理,1只能讀取2中數據,不能修改其中的數據,反之亦然。

 

三、尋路處理

1.navmesh行走面處理

a、將客戶端地圖整個行走面navmesh導出爲json數據放在服務器,服務器預計算所有凸多邊形和相鄰多邊形的連接關係

b、將整個地圖使用四叉樹進行所在區域分割,如一個區域最大有20個凸多邊形。分割目的快速定位獲取一個座標所在多邊形和區域

c、按上面劃分好的區域(AreaInfo)計算每個區域擁有那些凸多邊形。目的用於A*尋路遍歷消耗,減少遍歷運算消耗。

2.尋路計算

獲取A位置到B位置到移動路徑

a、使用 1-b中方法獲取A,B所在的區域

b、若A,B在同一凸多邊形,直接返回AB座標點爲路徑列表

c、若A,B不在同一凸多邊形,而在不同區域,直接使用它們所在區域進行A*尋路

d、若A,B不在同一區域,首先使用向量移位運算計算所經歷區域,然後合併遍歷多邊形列表,進行A*尋路計算

 

補充:d遠距離尋路運算可能失敗且耗性能,因此最好提前手動生成行走路線。當然服務器一般很少是有遠距離尋路,客戶端使用較多

 

四、補充

1.數據對象

a、存儲數據對象Role和戰鬥場景計算對象Player分開,Role對象類似Netty的channel爲之分配一個EventLoop(共享線程)線程進行邏輯處理,Player對象交給區域(AreaInfo)EventLoop線程隊列(獨佔線程)執行。

b、用戶數據和配置數據使用mongodb,日子數據使用mysql

 

2.服務器物理引擎

待研究,可參考libgdx移植物理引擎到服務器?

解決玩家對象重疊問題?

 

3.網絡通信

使用netty,消息隊列中間件?ZeroMQ或阿里的消息隊列?

 

4.沙盒對象同步

如我的世界中自己組裝的建築物怎麼同步?登陸地圖時對比客戶端和服務器的建築列表標示位(爲每個修改過的建築建立唯一ID標示位),然後服務器推送建築信息的具體信息(標示位,座標,構造...),客戶端緩存標示位,然後客戶端更具具體信息下載資源構造地圖面貌並進行緩存?

具體實現待研究

 

四、總結

使用此方式的優點可以動態分割地圖處理單元(AreaInfo),避免地圖人多時線程處理不過消息,或地圖人少時浪費線程資源,最大化利用cpu,實現負載均衡;缺點地圖分割的單位都限制在2點n次方。目前設計依然時一個服務器承載幾千人在一個進程中實現。如果需要更大的地圖,更多的在線人數,實現全區全服在一個地圖上,理論上使用多進程消息通信實現是可以的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章