天天看點

遊戲中的對象資源資訊管理

首先要說明的是資源格式。資源格式一般存放如下格式

資源

 |

 --- part0

 ----part1

 ----part2

 ...

一個很好的例子就是模型資訊檔案,在一個模型資訊檔案中,存放了整個物體的所有部分,每一個部分又是單獨的資訊。這樣做的目的在于遊戲中的換裝。

還有一個例子就是特效檔案,比如将一個門派的技能做為一個特效檔案,而這個特效檔案中包含了所有技能的技能特效。又或者說,當我們要實作不同等級的技能有不同特效的時候,就可以将一個技能做一個特效檔案,而特效檔案中存放的則是不同的等級的特效。

接下來就是要說明邏輯和渲染部分的劃分。有些遊戲是直接将渲染和邏輯嵌在一起的。這樣做我覺得非常不好,不便于後期擴充。加上渲染部分的東西在邏輯裡亂飛,也會幹擾清析度。并且,你不能假設所有寫邏輯的同伴都喜歡和圖形沾親帶故的。因為有必要将渲染部分和邏輯劃分開來。

一種常見的分法就是将渲染部分交給場景管理器,而由場景管理器引出一個場景對象。好比ogre中的entity 這個entity是挂接在場景切點上的。 在這個entity中,就包含了我們需要顯示和繪制的東西,如模型,特效,位置,材質等等東西。邏輯在使用的時候,隻需讓邏輯對象派生(class導出方式),或者嵌入(導出接口方式)這個場景對象,即可實作資訊的共享。我采用的是接口導出方式。

class isceneobject;

class cgameobject

{

...

  isceneobject *msceneobject;

};

劃分情況就是如此了。那我們如何與場景對象接口通信呢。場景對象接口需要提供一些什麼操作呢? 那些改變基礎屬性的,

如位置,方向,大小,移動,控制動畫等都是很直覺的。 那我們如何改變一個場景對象的渲染資訊? 改變這些渲染資訊的時候,又應該以什麼樣的方式來進行?

在此我們想到,邏輯中,一個對象都有他自身的各種屬性,如果這個對象需要被渲染,肯定也需要一些渲染資訊,如采用什麼哪些模型的part,模型上有哪些特效等。 直接的方案就是按照上面講的資源劃分方式提供如下資訊表。

struct srenderinfo

  tchar[64] szresfile;//存儲資訊的檔案名

  tchar[64] szresname;//資訊檔案中的資源名

那麼,當我們想要為場景中的一個人物增加一件裝備的時候,我們就可以像這樣提供一個接口。isceneobject::addpart(const

tchar* modelinfofile,const tchar* partname)=0;

而假設現在我有一個“肩膀”,肩膀是“天尊套裝”中的“肩膀”。那麼這個裝備的srenderinfo mrenderinfo結構的值是{_text("天尊套裝"),_text("肩膀")} 我們調用msceneobject->addpart(mrenderinfo->szresfile,mrenderinfo->szresname);便可以修改一個模型的肩膀,外部并不用關心這個模型的任何渲染過程。

那我們要增加一個特效呢? 要知道,特效是随時都在調用的,當你釋放一個技能的時候,特效被增加,當你技能放完了,特效又會被删除。 (有個例外的情況就是光環類技能,這種技能的特效是會随着技能的關閉才删除的)。 總的來說,我們就需要isceneobject::addeffect(const tchar* effectfile,const tchar* effectname)=0;接口。

那我們或許會想做些優化,比如當我穿戴同樣的裝備的時候,就可以不用再調用addpart了。嗯,或許你會說這種東西用不着優化,那好吧。那特效呢? 成十成百的人放特效的時候,如果他們都總是按着一個技能不停的放。你覺得會不會有必要呢?

減少了特效的切換,減少了許多api的調用,模型不用重新計算他的特效資訊,不需要重新挂接。 或許,可以用字元串比較的方式來斷定。比如們可以在addeffect内部檢查是不是已經有相同的特效存在了,是不是在同一位置。。這樣我們就可以不用做更多的工作。當然,這樣是可以的。 而外部呢,你有資訊在字元串亂飛的同時保證所有東西都正确嗎?

其實上面的解釋都不足以讓我搬出下面的東西,但是有時候它會讓程式寫着簡單。

想像一下,在配置檔案中, 我們總是會給資源一個索引,然後才是他真正的内容。我們很少看到一個東西用字元串來索引的,當然,也有,我沒有說沒有。我們是不是可以試着将所有資訊存放起來,然後用一個索引來索引它們呢? 比如現在有50個玩家出現在你的周圍,而他們穿的裝備中有50%是共同的,如果我們采用剛剛的方式,就會出現許多個sizeof(tchar)*64*2.并且,裝備模版,特效模版的資訊

如果沒有和他們放一起,會是多麼複雜的一件事。 但是,如果通過索引的話,僅僅是一個16位索引,就可以解決問題。其實我們一開始就可以這樣做,除了模型顯示資訊外,還有一些基礎資訊都是共同的,這就是我們經常提到的裝備模版。 當我們采用索引後,一切就變得簡單了。 用索引索引出這些資訊,再傳給場景對象,看起來多麼容易的一件事啊。

其實我現在不是這樣做的,我是在場景管理内部做了一個資源資訊表,這個表不管其它的,隻負責資源id,資源檔案和資源部分的對應關系。 而場景管理是不會加載任何的資源資訊的。 因為我根本不知道一個遊戲的資源配置檔案會寫成什麼樣,會用什麼寫(xml? ini,excel?)。于是,對外提供了一個注冊這些資源資訊到内部的接口。而當我們上面的接口則變成了

isceneobject::addpart(int resid);

isceneobject::addeffect(int resid);

看到了嗎? 我并沒有用modelid,和effectid.說明什麼呢,說明所有資源采用的是統一編号。 這樣做貌似不太好。但這樣在場景管理中就不再需要維護多種資源的資源表了。而上面這兩個函數的實作,則是根據資源索引取得資源資訊,然後就可以正式進行操作了。

或許,我們可以把這個映射交給寫邏輯的人處理,隻是不知道他們願不願意。

之是以寫出來,是因為我在猶豫,到底哪種方案更好,或者有沒有更好的方案來解決這個事情。。。。

簡介:09年入行,喜歡遊戲和程式設計,對3d遊戲和引擎尤其感興趣。 

版權聲明:本文版權歸作者和部落格園共有,歡迎轉載。轉載必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。

轉載:http://www.cnblogs.com/geniusalex/archive/2010/07/12/1940478.html