jdo*_*oig 4 inheritance f# discriminated-union
我正在为我的F#项目创建一个场景图:
root
->player_bob
-->torch
->enemy_1
-->extravagant_hat
-->enemies_cat_jess
--->fleas
--->fur_ball
->loot
Run Code Online (Sandbox Code Playgroud)
等等,等等.
每个项目都需要保存一组游戏对象来代表它的孩子.
例如,enemy1的列表包含猫和帽子,猫列表包含跳蚤和毛球
所以我计划让它们全部继承自一个包含描述对象子集合的集合的类.
现在回答我的问题: 我应该将子对象向下转换为GameObject,并将它们存储在"GameObject"基类的列表中,或者创建一个有区别的联合,例如
type SceneObject =
|Character of Character //e.g player, enemy, cat
|Item of Item //e.g hat, torch, furball
Run Code Online (Sandbox Code Playgroud)
并将对象存储为"SceneObjects"列表,以避免任何问题/开销,以及向上转换它们等.同时允许我描述在碰撞检测中不渲染和/或不使用对象的特殊情况,例如:声音发射器,陷阱触发器等
歧视的联合+继承组合是我最初的想法; 尽管如此,由于我是FP的新手,我认为向专业人士询问最佳,实用,接近这一点的方式是明智的.
谢谢,
JD
Dar*_*rio 10
您可以递归地使用区分联合.
type SceneObject =
| Character of <characterData> * (SceneObject list)
| Item of <itemData> * (SceneObject list)
Run Code Online (Sandbox Code Playgroud)
并像这样使用它
let root = [Character("Bob", [Item("Torch", []); ...]); ...]
Run Code Online (Sandbox Code Playgroud)
Dario建议的替代方法是为游戏中的实际对象声明一个单独的类型(例如项目和字符),并将其包装在另一个添加子对象列表的对象中.这看起来像这样:
type SceneObject =
| Character of <characterData>
| Item of <itemData>
type ObjectWithChildren =
{ Object : SceneObject
Children : ObjectWithChildren list }
Run Code Online (Sandbox Code Playgroud)
这两个选项都是正确的功能设计,但我更喜欢这个版本,因为它使某些类型的处理更容易.例如,如果要遍历游戏树中的所有对象,可以编写如下内容:
let rec traverse tree =
// Do something with tree.Object
for child in tree.Children do traverse child
Run Code Online (Sandbox Code Playgroud)
在此版本中,您根本不需要进行模式匹配SceneObject,因此您不需要包含所有情况(例如Item和Character).