2010-06-23 52 views
3

我正在一個小的網絡遊戲配置,其中有一個需要存儲對多(100+)不同種類的遊戲對象的信息的合理費用。代碼與遊戲對象庫

我想,以決定是否有通過代碼生成或存儲在一些配置文件中這一數據。

數據生成方法會是這樣的(在Java中上下的僞代碼):

(within a set of functions executed once at program startup) 
.... 
// create grass terrain 
grass=new GameObject(); 
grass.inheritProperties(generic_terrain); 
grass.set(NAME,grass); 
grass.set(MOVEABLE,true); 
grass.set(MOVECOST,10); 
grass.set(IMAGE_INDEX,1); 
.... 

儘管配置文件的方法將可能只是使用XML類型的格式如

(within terrain.xml file) 
.... 
<terrain name="grass"> 
    <inherit class="generic_terrain"/> 
    <property key="NAME" value="grass"/> 
    <property key="MOVABLE" value="true"/> 
    <property key="MOVECOST" value="10"/> 
    <property key="IMAGE_INDEX" value="1"/> 
</terrain> 
.... 

的一些要點:

  • 此信息是靜態的每個遊戲的遊戲運行時 (即不執行過程中不能改變 )
  • 屬性名稱(姓名,MOVECOST等。 )是一個相對較小的列表,但額外的節點可能隨着時間的推移
  • 它是安全 的假設,它只會得到 由開發改變被添加退役隊(即 在構建 過程之外不需要配置 )。
  • 這將需要發展 期間相當經常扭捏 遊戲平衡的原因(如決策單元更少/更強大)
  • 有以上基層需求的例子一定量的屬性的「繼承」,即擁有由generic_terrain定義的所有標準屬性以及一些新的添加/更改。

哪種方法將是最適合這種情況呢?更重要的是爲什麼?

+0

如果你正在尋找一個有效的配置文件格式,我建議考慮[YAML(http://www.yaml.org/):) – 2010-06-26 10:00:12

回答

5

我個人喜歡推儘可能多的配置成爲可能。原因是在某些時候,我可能希望以完全不同的方式重用我爲遊戲編寫的代碼。如果源代碼充斥着對實現特定細節的引用,則這變得更加困難。

當你想要開始描述除了它們的值之外的對象的行爲時,會出現一個有趣的配置方法警告。考慮一個簡單的例子,你有一個杯子對象需要「捕捉」球對象。你可能會這樣表達:

<object name="ball"> 
    <property key="shape" value="circle"/> 
    <property key="movable" value="true"/> 
    <property key="speed" value="10"/> 
</object> 

<object name="cup"> 
    <property key="shape" value="rectangle"/> 
    <property key="movable" value="true"/> 
    <property key="speed" value="6"/> 
    <property key="catches" value="ball"/> 
</object> 

這裏的問題是,你仍然需要在你的代碼裏面定義什麼「捕獲」。如果您使用的是解釋型語言,你可以這樣做:

<object name="cup"> 
    <property key="shape" value="rectangle"/> 
    <property key="movable" value="true"/> 
    <property key="speed" value="6"/> 

    <oncollision> 
     if (collided.getName() == "ball") { 
     collided.destroy(); 
     points++; 
     } 
    </oncollision> 
</object> 

現在你已獲得描述對象如何表現以及它所的能力。這裏唯一的問題是,如果你不使用解釋型語言,那麼在運行時就沒有奢侈的定義代碼。這是Lua在遊戲開發中如此流行的原因之一。它適用於聲明式和過程式語言,並且很容易嵌入編譯的應用程序中。所以你可以表達這樣的情況:

object { 
    name='ball'; 
    movable=true; 
    speed=10; 
} 

object { 
    name='cup'; 
    movable=true; 
    speed=6; 
    oncollision=function(collided)  
    if collided:getName() == "ball" then 
     collided:destroy(); 
     points++; 
    end 
    end; 
} 
2

從代碼中分離數據只是總是一個好主意。即使數據在執行期間是靜態的,它也不在設計過程中。使用硬編碼數據的遊戲比從易於修改的配置文件收集數據的遊戲靈活得多。

將數據保存在單獨的文件中,例如xml允許快速和簡單地更改各種值,您認爲這很重要。

+0

配置文件可以是一個單獨的即使它只是代碼文件。 – Tom 2010-06-24 10:22:38

2

這不是語言不可知的。

如果您使用的是編譯語言,請使用配置文件,這樣您就不會在每次調整某些內容時強制進行重新編譯。

如果您使用的語言不需要執行顯式的編譯/鏈接過程,請在代碼中執行,以便不必處理解析和加載。 (但是要在一個地方完成,以便完全替換功能很容易,如果將來需要這樣做的話)。

這裏的基本理念是代碼是數據,但有時代碼作爲數據很難修改;在這種情況下(例如編譯語言的情況),用一種更容易修改的代碼編寫它。 (您的解釋配置語言。)

+0

有趣......雖然個人來說,我從來沒有受到這種情況下重新編譯的代價的影響 - 如果編譯+運行所有測試需要三秒鐘(或者甚至更好地在後臺自動運行),那麼它可能不會花費你不僅僅是導航到/從單獨的配置文件。 – mikera 2010-06-23 19:30:16

+0

如果你有使用動態加載的庫的奢侈,我想這可能是這種情況。編譯/鏈接我工作的系統,如果只更改一個.cpp文件,大約需要45秒。所以YMMV就是這個。 – pkh 2010-06-24 00:31:27

2

很多遊戲引擎都使用腳本語言,這是因爲您提到的許多原因。 Lua是一款非常棒的,速度相當快的輕量級腳本引擎,已經在很多遊戲中取得了巨大的成功。您可以輕鬆地使用解析器來完成簡單的配置設置並保留它,或者構建更多功能並讓實際代碼寫入文件。你在lua中的例子可能是這樣的:

grass = { 
    NAME = "grass", 
    MOVEABLE = true, 
    MOVECOST = 10, 
    IMAGE_INDEX = 1 
} 

setmetatable(grass, generic_terrain) 
+0

因此,如果我理解正確的話,Lua會落入「代碼」陣營,但是會以輕量級的特定領域語言進行處理,並動態運行它以使其表現得更像配置文件? – mikera 2010-06-23 19:32:03

+0

如果你想以這種方式設置它,它可以表現得像一個簡單的配置文件。 Lua的基本數據結構是一個表(它是一個組合的散列表和數組),這使得它對於配置語言來說工作得很好。 – Dolphin 2010-06-24 20:49:15

2

如果你確實選擇使用XML,至少應該嘗試使用一個健全的模式。當它被設計成直接表示那些東西時,沒有理由將自己的小模式(「對象」,「屬性」,「鍵」,「值」)嵌入到XML中。如何:

<ball> 
    <shape>circle</shape> 
    <movable>true</movable> 
    <speed>10</speed> 
</ball> 

<cup> 
    <shape>rectangle</shape> 
    <movable>true</movable> 
    <speed>6</speed> 
    <catches>ball</catches/> 
</cup>