• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            loop_in_codes

            低調做技術__歡迎移步我的獨立博客 codemaro.com 微博 kevinlynx

            MMO游戲對象屬性設計

            MMO游戲對象屬性設計

            Author: Kevin Lynx
            Date: 5.2.2011

            一般的MMORPG中,游戲對象主要包括怪物和玩家。這兩類對象在經過游戲性方面的不斷“進化”后,其屬性數量及與之相關的邏輯往往會變得很巨大。如何將這一塊做得既不損失效率,又能保證結構的靈活、清晰、可維護?本文將提供一種簡單的結構。

            原始結構

            最原始的結構,極有可能為這樣:

            Player:     +---------------+
                        | property-1    |
                        +---------------+
                        | property-2    |
                        +---------------+
                        |     ...       |
                        +---------------+
                        | operator-1    |
                        +---------------+
                        | operator-2    |
                        +---------------+
                        | ...           |
                        +---------------+
            

            也就是,一個對象為一個C++類,然后里面直接塞滿了各種屬性名,然后是針對這個屬性的邏輯操作(函數)。其結果就是Player成為巨類。針對這個情況,一直以來我覺得可以使用一種簡單的方法來拆分這個類。冠以官腔,稱之為Entity-Component-based Desgin。產生這種想法和我的個人技術積累有一定關系,見下文。

            Policy-based Design

            Policy-based Design,基于決策的設計。這個概念來源于<Modern C++ Design>。雖然這本書講述的是針對C++模板的使用及設計技巧。但這種思想依然被我潛意識般地用在其他地方。Policy大致來說就是一個小的組件(Component)。它努力不依賴于其他東西,它可能就是個簡單的類,它擁有極少的數據結構,及針對這些數據的極少操作接口。舉例而言,玩家MP的自動回復功能,就可封裝為一個Policy。將許多Policy組合起來,就可完成一個復雜的功能。

            這種思想還可指導很多程序結構方面的設計。例如在做功能的接口拆分時,就將每個函數設計得足夠小,小到單純地完成一個功能。一個功能的入口函數,就將之前實現的小函數全部組合起來,然后共同完成功能點。

            當然,<Modern C++ Design>里的Policy在表現形式上有所不同。但其核心思想相同,主要體現在 組合 特點上。

            Entity-Component-based Design

            Entity-Component-based Design按照google到的文章,嚴格來說算是與OOP完全不同的軟件設計方法。不過在這里它將按照我的意思重新被解釋。

            如果說Policy-based Design極大可能地影響著我們平時的細節編碼,那么Entity-Component則是直接對游戲對象的結構設計做直接的說明。 一個游戲對象就是一個Entity。 Entity擁有很少的屬性,也許僅包含一個全局標示的ID。 一個Component則是Entity的某個行為、或者說某個組成部分。 其實說白了,以玩家為例,一個玩家對象就是一個Entity,而一個MP的自動回復功能就可被包裝為一個Component。這個Component可能包含若干與該功能相關的數據,例如回復時間間隔,每次的回復量等。我們往玩家對象這個Entity添加各種Component,也就是給玩家添加各種邏輯功能。

            但是,Component之間可能會涉及到交互,玩家對象之外的模塊可能也會與玩家內的某個Component交互。子功能點的拆分,不得不涉及到更多的膠水代碼,這也算一種代價。

            游戲對象屬性設計

            這份屬性結構設計,基本就是參考了上面提到的設計思想。整個系統有如下組件:

            Entity:    +-------------------+
                       | property-table    |
                       +-------------------+
                       | component-table   |
                       +-------------------+
            Property:  +-------------------+
                       | observer-list     |
                       +-------------------+
            Component: +--------------------+
                       | logic-related data |
                       +--------------------+
                       | logic-related func |
                       +--------------------+
            

            意即,所有Entity都包含一個屬性表和組件表。這里的屬性表并非硬編碼的屬性數據成員集合,而是一個key-value形式的表。Property包含一個觀察者列表,其實就是一系列回調函數,但是這些觀察者本質上也是組件,后面會提到。Component正如上文描述,僅包含Component本身實現的功能所需要的數據和函數。整個結構大致的代碼如下:

            class Entity {
            private:
                GUID id;
                std::map<std::string, IComponent*> components;
                std::map<std::string, Property*> properties;
            };
            class Property {
            private:
                std::string name;
                Value val;
                std::vector<IComponent*> observers;
            };
            class IComponent {
            public:
                virtual bool Operate (const Args &args) { return false; }
                virtual void OnNotify (const Property &property, const Args &args) {}
            protected:
                std::string name;
                Entity *entity;
            };
            

            屬性本身是抽象的,這完全是因為我們將屬性統一地放在了一個表里。從而又導致屬性的值也需要繼續閱讀

            posted on 2011-05-02 19:19 Kevin Lynx 閱讀(7020) 評論(18)  編輯 收藏 引用 所屬分類: game develop 、模塊架構

            評論

            # re: MMO游戲對象屬性設計 2011-05-02 20:19 so

            MUD游戲編程里也有屬性集這樣的設計。靈活。不過訪問速度上肯定沒有直接定死屬性來得快。  回復  更多評論   

            # re: MMO游戲對象屬性設計 2011-05-02 20:36 Kevin Lynx

            @so
            加了個“繼續閱讀”指向我那個獨立博客。- -| 你都要在這里留言。  回復  更多評論   

            # re: MMO游戲對象屬性設計 2011-05-03 10:33 lin_style

            有個問題:是否代碼行數多、屬性多,就代表他的邏輯一定是復雜的?一定要拆分?  回復  更多評論   

            # re: MMO游戲對象屬性設計 2011-05-03 12:02 飯中淹

            你那個獨立博客在CHROME上會標紅標骷髏頭。

              回復  更多評論   

            # re: MMO游戲對象屬性設計 2011-05-03 12:03 Kevin Lynx

            @lin_style
            基本上是。雖然邏輯不一定復雜,可能僅僅是大量功能的堆積。但其維護性肯定不好?;貞浺幌庐斈銊偨邮质煜ひ粋€項目代碼時,看到一個巨類時的感覺。  回復  更多評論   

            # re: MMO游戲對象屬性設計 2011-05-03 12:11 Kevin Lynx

            @飯中淹
            Linux下的chrome看沒有什么骷髏頭啊。。- -|  回復  更多評論   

            # re: MMO游戲對象屬性設計 2011-05-03 12:51 lin_style

            @Kevin Lynx
            如果能夠一遍就看懂“巨類”,我可能覺得這種分類方式是對的。比如人物屬性,人物本來就有這么多屬性啊。而且這些屬性放在一起,并沒有很復雜的讀取邏輯,即使有不同的功能拓展,那也是每個功能類自己的模塊化問題。你文中,"ClientUpdater" “HP”,從概念上都分成獨立的屬性模塊."ClientUpdater"有必要這么做,但是也可以看成一個功能模塊類去維護它,況且它也是屬于游戲玩法類的,放在屬性接口層也不一定合適。而"HP",是一個很清晰的概念,不需要專門的封裝它,即使有hP1~HP1000這么多屬性,也沒有帶來多高的復雜讀。如果僅是憑借自己的編程習慣去封裝,那這個過與不過的度怎么區分呢?  回復  更多評論   

            # re: MMO游戲對象屬性設計 2011-05-03 13:57 Kevin Lynx

            @lin_style
            復雜性和可維護性不僅體現在本項目,一般一個團隊的下個項目就是在上個項目的基礎上改。所以希望把這些游戲相關的東西盡量獨立出來。理想情況下是到了下個項目可以直接通過移除一部分模塊添加一部分模塊即可。

            當然,如你所說,確實存在度的把握問題。我現在是打算把基礎屬性(例如坐標)寫死,或者通過本文的機制在程序里添加;其他屬性(主要是戰斗屬性、什么中毒抗性啊、暴擊傷害比率啊)放在腳本或配置里擴展。

            但是如果是做引擎,這些包裝則是必須的了。
            ps. 因為在團隊里某部分代碼可能會在時間線上由不同的人修改,盡早地提出一種明顯的規則,可以約束后面的人不至于隨意而為。如果一開始就在Player類里塞功能,早期可能沒問題,不過隨著項目進展,后面的人極有可能模仿前人的做法,最終就會導致不斷地在Player里加功能代碼。膨脹由此而來。  回復  更多評論   

            # re: MMO游戲對象屬性設計 2011-05-03 15:58 飯中淹

            接著我在那邊跟你說的,我是不允許代碼和腳本碰數據對象的屬性的。

            屬性必須由對象設計器生成。這個對象設計器是在線的,也就是運行時創建,更改的。

            映射也是,映射說起來就是一種腳本,用來關聯對象之間的屬性的東西。


              回復  更多評論   

            # re: MMO游戲對象屬性設計 2011-05-03 16:06 Kevin Lynx

            @飯中淹
            話說你把你們的服務器整成全部配置驅動的;而我們在向全部腳本驅動靠近。  回復  更多評論   

            # re: MMO游戲對象屬性設計 2011-05-03 17:58 飯中淹

            @Kevin Lynx
            配置+腳本共同的
            每個都可以實時修改
            這樣該錯誤,更新什么的,根本不用重啟了

            服務器本身的程序就是一堆底層的庫在那里

            然后就是支持這些數據對象和映射。

            數據對象雖然看起來很復雜,實際上是個簡單功能的容器類,和封包的結構很像。

            大部分的事情都是在映射里做的。而這些映射都是腳本的。


            腳本我準備用quartz composer那種卡片式的,這樣可以用IPAD,GPAD,樂PAD等各種PAD,用3G卡在某個公園的角落里摸幾下就把服務器BUG給修改好了。





              回復  更多評論   

            # re: MMO游戲對象屬性設計 2011-05-03 18:01 飯中淹

            @Kevin Lynx
            數據也腳本化,我感覺不合適。

            我是要提供可視化編輯工具給策劃,讓他們自己去設計數據對象。

            腳本這些粗活,就是服務器程序來做。

            所有工具都做成各種PAD可部署的,這樣就不用限制辦公地點和時間了。

            隨時隨地做事。

            有個好的點子可以立即應用到實際的游戲服務中去。

              回復  更多評論   

            # re: MMO游戲對象屬性設計 2011-05-03 18:05 Kevin Lynx

            @飯中淹
            我們這回策劃將編寫大量腳本。瞬間在策劃組掀起了學習Lua的熱潮。整體架子的發展路線,和你說的差不多。程序這邊僅提供底層功能實現。  回復  更多評論   

            # re: MMO游戲對象屬性設計[未登錄] 2011-05-03 18:15 楊粼波

            數據還是放到配置里面的好,比如csv,xml。
            放腳本里面可以,但是編輯性不好啊。  回復  更多評論   

            # re: MMO游戲對象屬性設計 2011-05-03 19:37 Kevin Lynx

            @楊粼波
            這倒提醒我了。還真是不方便編輯。  回復  更多評論   

            # re: MMO游戲對象屬性設計 2011-05-03 23:20 cui

            都是單線程的服務? 多線程的服務實時更新配置文件,需要加的互斥太多了  回復  更多評論   

            # re: MMO游戲對象屬性設計 2011-05-06 10:55

            @Kevin Lynx
            @飯中淹

            配置驅動與腳本驅動,我更偏向配置驅動,腳本太靈活了,debug的難度很大,要求高,不宜開放出去。配置驅動配置死了點,但是安全穩定。寫一個配置編輯器來控制錯誤相對比較簡單。

            贊同@飯中淹 “不允許代碼和腳本碰數據對象的屬性的”,不然實在是非常危險。對于腳本,應該再封裝一層api。  回復  更多評論   

            # re: MMO游戲對象屬性設計 2012-02-08 17:41 阿飛

            拜讀中,繼續學習!  回復  更多評論   

            久久久久99这里有精品10| 日韩精品国产自在久久现线拍 | 久久久久97国产精华液好用吗| 国产精品九九九久久九九| 久久99毛片免费观看不卡| 久久久久噜噜噜亚洲熟女综合| 久久福利资源国产精品999| 91精品国产高清91久久久久久| 香蕉久久夜色精品国产小说| 无码任你躁久久久久久老妇| 久久大香香蕉国产| 日本亚洲色大成网站WWW久久| 99久久国产综合精品女同图片| 欧美精品一本久久男人的天堂| 久久久午夜精品| 精品人妻伦九区久久AAA片69| 精品国产乱码久久久久久呢| 一本久久a久久精品综合夜夜| 久久久久久久久66精品片| 精品无码人妻久久久久久| 久久综合久久自在自线精品自| 日韩久久无码免费毛片软件| 久久亚洲AV成人无码电影| 久久久久亚洲av毛片大| 日韩精品久久久久久| 精品蜜臀久久久久99网站| 亚洲人成网亚洲欧洲无码久久| 国产三级观看久久| 亚洲国产天堂久久综合网站| 蜜臀av性久久久久蜜臀aⅴ麻豆 | 久久久久亚洲AV无码观看| 久久久亚洲精品蜜桃臀| 伊人久久大香线蕉精品| 国产精品激情综合久久| 精品无码久久久久久国产| 国产99久久久久久免费看| 久久久久久综合一区中文字幕| 精品久久久久久| 国产福利电影一区二区三区久久老子无码午夜伦不| 久久精品aⅴ无码中文字字幕不卡| 欧美大战日韩91综合一区婷婷久久青草|