MMO游戲?qū)ο髮傩栽O(shè)計(jì)
MMO游戲?qū)ο髮傩栽O(shè)計(jì)
Author: | Kevin Lynx |
---|---|
Date: | 5.2.2011 |
一般的MMORPG中,游戲?qū)ο笾饕ü治锖屯婕摇_@兩類對(duì)象在經(jīng)過游戲性方面的不斷“進(jìn)化”后,其屬性數(shù)量及與之相關(guān)的邏輯往往會(huì)變得很巨大。如何將這一塊做得既不損失效率,又能保證結(jié)構(gòu)的靈活、清晰、可維護(hù)?本文將提供一種簡(jiǎn)單的結(jié)構(gòu)。
原始結(jié)構(gòu)
最原始的結(jié)構(gòu),極有可能為這樣:
Player: +---------------+ | property-1 | +---------------+ | property-2 | +---------------+ | ... | +---------------+ | operator-1 | +---------------+ | operator-2 | +---------------+ | ... | +---------------+
也就是,一個(gè)對(duì)象為一個(gè)C++類,然后里面直接塞滿了各種屬性名,然后是針對(duì)這個(gè)屬性的邏輯操作(函數(shù))。其結(jié)果就是Player成為巨類。針對(duì)這個(gè)情況,一直以來我覺得可以使用一種簡(jiǎn)單的方法來拆分這個(gè)類。冠以官腔,稱之為Entity-Component-based Desgin。產(chǎn)生這種想法和我的個(gè)人技術(shù)積累有一定關(guān)系,見下文。
Policy-based Design
Policy-based Design,基于決策的設(shè)計(jì)。這個(gè)概念來源于<Modern C++ Design>。雖然這本書講述的是針對(duì)C++模板的使用及設(shè)計(jì)技巧。但這種思想依然被我潛意識(shí)般地用在其他地方。Policy大致來說就是一個(gè)小的組件(Component)。它努力不依賴于其他東西,它可能就是個(gè)簡(jiǎn)單的類,它擁有極少的數(shù)據(jù)結(jié)構(gòu),及針對(duì)這些數(shù)據(jù)的極少操作接口。舉例而言,玩家MP的自動(dòng)回復(fù)功能,就可封裝為一個(gè)Policy。將許多Policy組合起來,就可完成一個(gè)復(fù)雜的功能。
這種思想還可指導(dǎo)很多程序結(jié)構(gòu)方面的設(shè)計(jì)。例如在做功能的接口拆分時(shí),就將每個(gè)函數(shù)設(shè)計(jì)得足夠小,小到單純地完成一個(gè)功能。一個(gè)功能的入口函數(shù),就將之前實(shí)現(xiàn)的小函數(shù)全部組合起來,然后共同完成功能點(diǎn)。
當(dāng)然,<Modern C++ Design>里的Policy在表現(xiàn)形式上有所不同。但其核心思想相同,主要體現(xiàn)在 組合 特點(diǎn)上。
Entity-Component-based Design
Entity-Component-based Design按照google到的文章,嚴(yán)格來說算是與OOP完全不同的軟件設(shè)計(jì)方法。不過在這里它將按照我的意思重新被解釋。
如果說Policy-based Design極大可能地影響著我們平時(shí)的細(xì)節(jié)編碼,那么Entity-Component則是直接對(duì)游戲?qū)ο蟮慕Y(jié)構(gòu)設(shè)計(jì)做直接的說明。 一個(gè)游戲?qū)ο缶褪且粋€(gè)Entity。 Entity擁有很少的屬性,也許僅包含一個(gè)全局標(biāo)示的ID。 一個(gè)Component則是Entity的某個(gè)行為、或者說某個(gè)組成部分。 其實(shí)說白了,以玩家為例,一個(gè)玩家對(duì)象就是一個(gè)Entity,而一個(gè)MP的自動(dòng)回復(fù)功能就可被包裝為一個(gè)Component。這個(gè)Component可能包含若干與該功能相關(guān)的數(shù)據(jù),例如回復(fù)時(shí)間間隔,每次的回復(fù)量等。我們往玩家對(duì)象這個(gè)Entity添加各種Component,也就是給玩家添加各種邏輯功能。
但是,Component之間可能會(huì)涉及到交互,玩家對(duì)象之外的模塊可能也會(huì)與玩家內(nèi)的某個(gè)Component交互。子功能點(diǎn)的拆分,不得不涉及到更多的膠水代碼,這也算一種代價(jià)。
游戲?qū)ο髮傩栽O(shè)計(jì)
這份屬性結(jié)構(gòu)設(shè)計(jì),基本就是參考了上面提到的設(shè)計(jì)思想。整個(gè)系統(tǒng)有如下組件:
Entity: +-------------------+ | property-table | +-------------------+ | component-table | +-------------------+ Property: +-------------------+ | observer-list | +-------------------+ Component: +--------------------+ | logic-related data | +--------------------+ | logic-related func | +--------------------+
意即,所有Entity都包含一個(gè)屬性表和組件表。這里的屬性表并非硬編碼的屬性數(shù)據(jù)成員集合,而是一個(gè)key-value形式的表。Property包含一個(gè)觀察者列表,其實(shí)就是一系列回調(diào)函數(shù),但是這些觀察者本質(zhì)上也是組件,后面會(huì)提到。Component正如上文描述,僅包含Component本身實(shí)現(xiàn)的功能所需要的數(shù)據(jù)和函數(shù)。整個(gè)結(jié)構(gòu)大致的代碼如下:
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; };
屬性本身是抽象的,這完全是因?yàn)槲覀儗傩越y(tǒng)一地放在了一個(gè)表里。從而又導(dǎo)致屬性的值也需要繼續(xù)閱讀
posted on 2011-05-02 19:19 Kevin Lynx 閱讀(7021) 評(píng)論(18) 編輯 收藏 引用 所屬分類: game develop 、模塊架構(gòu)