場景管理之消息發送
好久沒有寫東西出來和大家共同揣摩,真是對不住大家了。現在終于騰了一些時間來繼續和大家研究網絡游戲制作技術,在這一節中,我就要向大家介紹網絡游戲服務器中World場景劃分和場景中消息分發問題。
在前面我基本向大家講述的都是一些基本的技術問題,從某種意義上講。屬于純技術范疇的東西,但現在要向大家講的,應該是屬于服務器功能設計范疇的。在這里,我未必講的很好,有遺漏之處就請大家諒解和指正。
對于有一定游戲服務器開發基礎的朋友而言,應該都明白一個網絡游戲服務器和客戶端之間的一個基本關系: 玩家客戶端是游戲服務器一個局部COPY表現。這個說法聽起來可能有一些繞口,簡單的解釋下也就是說:客戶端所具備的區域信息也就是游戲服務器相同區域數據的一份COPY,而表現的意思,也就是說,CLIENT端將這樣的數據信息圖形化,并且通過屏幕來進行顯示,從而來呈現出一個多姿多彩的游戲世界。這樣說大家應該能夠聽懂了吧?再不懂的話,就自己琢磨了。
說了上面那么多,大家一定要問“SERVER和CLIENT這種關系和我們的消息發送又有什么關系呢?”。其實,我們要討論的問題點也就在這里。但現在我還不說場景消息到底該如何進行分發。我們還是再來研究一個問題:什么能夠使我們的游戲世界變的內容豐富?
大家先不要看我所說的,先自己想想。
大家應該都思考過了,我就來說一下我的個人想法和理解,可能和大家不一樣(我想到的你沒有想到的你補上,反之,我補上)。
在我們的MMOPRG游戲世界中,造成游戲世界變的豐富多彩一般無外乎兩個大方面:NPC動作、玩家動作。呵呵,看起來就只有簡單的兩個方面,但具體分析這些動作起來,可就會讓各位包括我都會頭大的。先我們來說NPC動作吧,NPC動作通過AI邏輯進行控制,一般情況可以分為一下幾個動作:待機、移動、物理攻擊、技能攻擊、魔法攻擊、死亡等,而游戲中玩家動作的產生是由現實中玩家進行操控的,動作類型基本上也不外乎以上幾種。既然在服務器游戲世界中存在這樣的一些動作,那是如何進行獲取的呢?其實就只有兩個字:消息(Message)。而消息的產生方又分為兩種:Client消息,Server消息。既然有消息產生,我們就將涉及到另外一個問題:如何將產生的消息分發出去呢?
下面通過我自己的實現經驗來簡單介紹場景消息的分發原理(詳細介紹寫的太多,有點懶!!),應該不是最佳的,我只是提一個開頭,更好的處理實現方式還是需要大家來共同研究。有好的想法也希望告訴我下,我也從中學習些新的東西。
先看場景示范圖(我畫的,比較土,只是表明一個意思。呵呵)
通過上面設計示范圖,我來具體介紹:關于場景消息分發,我的設計和分析過程:
第一步:將場景網絡化,也就是說將我們的游戲服務器大場景進行邏輯上的區域劃分,每個單獨區域所占的面積可以考慮比屏幕區域稍微大點。同時為每一個單獨的區域創建Player標志信息(SOCKET或者其他)列表。
第二步:將單獨區域四分化,也就是說對于每一個小區域,再次劃分為四個更加小的區域,同時為每一個小的區域建立一個包含三個對象的整數數組。數組的作用是為了保存此小區域的親緣區域。例如: 小區域1的親緣區域就是: A、B、H,小區域2的親緣區域就是:B、C、D等。
第三步:在上面兩步基礎上,就是實際處理消息分發了。如果Player/NPC在區域中進行消息動作,我們通過Player/NPC的當前位置就可以首先確定Player/NPC所在大地圖中的具體區域。在我們確定好了具體的區域后,我們要繼續確定在那個具體的小區域。在這些小區域都確定后,我們就可以將我們的動作消息發送到親緣區域中的Player(玩家)。
第四步:對于第三步的改變優化,用CPU處理量來換取消息數量,具體做法也就是,在親緣區域中繼續區域化。也就是說消息不是發送到親緣區域中的所有Player(玩家),而是有選擇的發送到自身一定區域的玩家。這種優化改革從某種意義上講,可以減少服務器總消息數量,但增大CPU處理量,而對于具體實現,就需要大家去權衡了。
以上也就是這個分析和處理過程了。同時關于這個場景處理的.h文件,我也就簡單的寫下,大家參考了。
Class GmapRegion
{
public:
GmapRegion();
~ GmapRegion();
void GetBoardCastMsgList(POINT current_pos,LIST *); //獲取當前位置廣播消息的Player列表。
……..
private:
void Init();
voud Release();
bool InitMapRegion(int map_wis,int map_hei); //地圖區域化
protected:
}