2010-08-29 134 views
3

我期待創造一個場景圖我的F#項目的財產以後這樣的:識別聯合和繼承

root 
->player_bob 
-->torch 
->enemy_1 
-->extravagant_hat 
-->enemies_cat_jess 
--->fleas 
--->fur_ball 
->loot 

等等,等等。

每個項目需要保存一個遊戲對象的集合來表示它的孩子。

e.g enemy1的列表中包含一隻貓和一頂帽子和貓列表包含跳蚤和毛球

所以我打算讓他們都從包含描述對象的子對象的集合類繼承。

現在我的問題: 我應該向下轉換子對象遊戲對象的,並把它們存儲在「遊戲對象」基類 的清單,或建立一個識別工會如

type SceneObject = 
     |Character of Character //e.g player, enemy, cat 
     |Item of Item //e.g hat, torch, furball 

和存儲對象作爲「場景對象」的列表以避免任何問題/開銷的上演,等等。以及允許我描述在碰撞檢測中不呈現和/或不使用對象的特殊情況,例如:聲音發射器,陷阱觸發器等。

歧視的工會+繼承組合是我最初的想法;不過,因爲我是FP新手,所以我認爲向專業人士提供最好的,實用的解決方法是明智的。

感謝,

JD

回答

9

可以使用識別聯合遞歸

type SceneObject = 
    | Character of <characterData> * (SceneObject list) 
    | Item  of <itemData>  * (SceneObject list) 

而且使用這樣的

let root = [Character("Bob", [Item("Torch", []); ...]); ...] 
+1

太棒了!這消除了對繼承的需求:¬) 謝謝Dario,我的一半學習FP的問題正在把我的腦袋從OO土地中拉出來。 – jdoig 2010-08-29 11:29:46

7

什麼達里奧建議另一種方法是申報在遊戲中的實際對象單獨的類型(如項目和字符)和另一對象把它包它添加了一個子對象列表。這應該是這樣的:

type SceneObject = 
    | Character of <characterData> 
    | Item of <itemData> 

type ObjectWithChildren = 
    { Object : SceneObject 
    Children : ObjectWithChildren list } 

的選項都正確的功能設計,但我寧願這個版本,因爲它使某些類型的處理更容易。例如,如果你想穿越遊戲中的樹中的所有對象,你可以寫這樣的:

let rec traverse tree = 
    // Do something with tree.Object 
    for child in tree.Children do traverse child 

在這個版本中,你並不需要在SceneObject模式匹配好,所以你不需要包括所有的案例(如ItemCharacter)。

+0

有趣。這就是我對Character類及其狀態機進行建模的方式。 保存所有原始數據(位置,健康等)的字符記錄(CharacterRecord)。 一個郵箱處理器作爲狀態機(CharacterStateMachine)。 然後將它們包裝在「Character」記錄中,該記錄包含{state:CharacterStateMachine;數據:CharacterRecord}。 然後使用的成員,使一些用戶友好的getter和setter ... 所以這種解決方案很適合我目前的模型。 我將不得不給這兩個嘗試, 非常感謝。 – jdoig 2010-08-29 21:53:16