2010-08-29 2 views
3

Я ищу, чтобы создать сцену-граф для моего F # проекта Somthing как:дискриминированных союзы и наследование

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

и т.д., и т.д..

Каждый предмет должен содержать коллекцию игровых объектов для представления своих детей.

enemy1 например Перечислит содержит кошку и шляпу, и список кошек содержат блоха и мехового мяч

Так что я планирую сделать их все наследовать от класса, который содержит коллекцию, которая описывает, что объекты детей.

Теперь мой вопрос: Должен ли я вниз отливка ребенок возражает GameObject-х и хранить их в списке «геймобжекты» базового класса или создать разборчивого накидной например

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

И магазин объекты в виде списка «SceneObjects», чтобы избежать проблем/накладных расходов с их перетаскиванием и т. д. Также, позволяя описывать особые случаи, когда объект не отображается и/или не используется при обнаружении конфликтов, например: звуковые излучатели , триггеры ловушек и т. д.

Дискриминационный союз + наследование комбо - моя первоначальная мысль; хотя, поскольку я новичок в FP, я подумал, что было бы разумно спросить профессионала о лучшем, функциональном, способе приблизиться к этому.

Спасибо,

JD

ответ

9

Вы можете использовать дискриминационный объединение рекурсивно.

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

И использовать его как этот

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

Блестящий! Это устраняет необходимость в наследовании: ¬) Спасибо Дарио, половина моей проблемы с обучением FP вытаскивает мою голову из земли OO. – jdoig

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 на всех, так что вы не необходимо включить все случаи (например, Item и Character).

+0

Интересно. Вот как я смоделировал класс Character и его конечный автомат. Символьная запись для хранения всех необработанных данных (местоположение, работоспособность и т. Д.) (CharacterRecord). Обработчик почтового ящика как конечный автомат (CharacterStateMachine). И затем обернуты два в записи «Персонаж», которая содержит {state: CharacterStateMachine; данные: CharacterRecord}. Затем использовались члены, чтобы сделать удобные геттеры и сеттеры ... Итак, это решение хорошо подходит для моей текущей модели. Я должен дать обе эти попытки, Большое спасибо. – jdoig

Смежные вопросы