傳統的遊戲對象管理系統採用繼承的方式來實現,例如,全部的子類都從CObject派生。大多數狀況下,直接派 生的也是抽象類,其中帶一些功能而另外一些子類則不帶這些功能,好比可控制/不可控制,可動畫/不可動畫等。mangos的實現中基本就是這種狀況,從 Object直接派生的Unit和WorldObject都是不可直接實例化的類。編程
傳統方法的問題在於沒法應對需求的變化,如要求武器也有動畫效果時就沒法處理了。若是硬要是這樣作,那隨着需求的嗇,不少的方法會被放到基類中,最終的結果是繼承樹變得愈來愈頭重腳輕,這樣的類會喪失它的內聚性,由於它們試圖爲全部對象完成全部的事。動畫
就是說到最後,基類會有一個很長的接口列表,而不少的遊戲對象類型根本不須要實現其中的一些甚至大部分接口,可是按照這種結構卻又必須去實現。以致於於實現一個很是龐大的對象,並且想要修改一點功能會致使系統的大調整。spa
咱們但願的系統是能夠將現有的功能組合到新的對象中,而且在將新的功能添加到現有的對象中時不須要重構大量的代碼和調整繼承樹的結構。指針
實現的方法就是從組件來建立一個對象。組件是一個包含全部相關數據成員和方法的類,它完成某個特定的任務。把幾 個組件組合在一塊兒就能夠建立一個新的對象。如把Entity組件、Render組件和Collectable組件組合在一塊兒生成了一個Spoon對象。 Entity組件讓咱們能夠把對象放到遊戲世界中,Render組件讓咱們能夠爲對象指定一個模型進行渲染,而Collectable組件讓咱們能夠拾取 這個對象。xml
關於組件的實現,全部的組件都從一個基礎組件接口派生,可稱其爲IComponent。每一個組件也有本身的接口定義,而且這個接口也須要從IComponent派生,相似於這樣:IComponent -- ICmpRender -- CCmpRender對象
這裏的每一個組件也就是我在上一篇中所說的由引擎提供的屬性,或者說在BigWorld中本身實現而後定義的屬 性,或者使用mangos中的定義,就是一個個的System,雖然mangos並無將其徹底作成組件,可是經過其代碼註釋能夠看到,接口也是按功能組 進行了分類,若是要拆分紅組件也是比較方便的。繼承
組件之間的通訊有兩種方法,一是用組件ID查詢到組件接口指針,而後調用接口方法;二是使用消息的方式,向對象中全部組件發消息。在初始化的時候,每個組件類型都會告訴對象管理器應該接收什麼樣的消息。接口
查詢接口的方法也就是直接的方法調用,只不過接口不是所有在基類中,因此必須先查詢到指定的組件而後才能調用其接口。消息的使用前面已經說過屢次,其實現方案也有過說明。遊戲
最後是關於遊戲對象功能的擴展和遊戲對象的定義。須要擴展功能也就是須要實現一個新的組件,或者修改如今組件。在大多數狀況下,擴展都不會引發結構的很大調整,受影響的最多隻是使用到該組件的部分代碼。it
遊戲對象定義可採用徹底數據驅動的方式,使用xml或者腳本語言來定義對象類型,以及每一個類型須要加載的組件。對象類型註冊到對象管理器後,由管理器提供建立指定類型的對象的方法。數據驅動的方式可以讓策劃自由定義遊戲對象類型,而且隨時可自由建立新的對象類型。