我想为我的游戏设计一个实体系统,只使用C和C++的一个子集。许多人使用继承来实现这一点,但我偶然发现了标记的联合,并了解到通过这种方式可以实现类似的结果,因为虚拟功能对游戏来说很慢(所以我从Casey Mouratori和Jon Blow这两位游戏开发人员那里听说,我从中获得了很多灵感(。
struct Unit {
int type;
int hp;
union {
struct {
int kingID;
} soldier_data;
struct {
string name;
} king_data;
};
}
Jon Blow避免使用他的新语言Jai中的一些功能来实现虚拟函数,Jai还没有发布,所以上面的例子是我唯一的想法。
例如,我只能编写一个Update函数,并使用该类型来区分实体。这将是一个非常大的函数,但是嘿,我们避免虚拟函数。
事情是我的游戏包含了士兵和树木。树是静态的,基本上什么都不做,所以我会为树实体写另一个更轻的结构,以节省一些内存,并使用并集来存储不同类型的树:
struct TreeEntity {
Texture* texture;
union {
struct {
int height;
} pineTree_data;
struct {
string name;
} coconutTree_data;
}
}
我面临的问题是,如果士兵和树都可点击怎么办?如果我使用了继承,我只需要一个函数Entity*selectEntity((,然后检查实例类型,但使用我的方法,我有点迷失了方向。
我的方法不好吗?我应该坚持使用虚拟函数吗?还是有办法处理这个问题?
您询问如何创建一个通用的Entity* selectEntity()
函数,该函数可以返回Unit*或Tree*(或者其他东西(。
可以通过返回基类指针来实现。Unit和Tree继承自Entity,Entity可以包含一个小枚举,如:
enum class EntityType : uint8_t {
Unit, Tree, // ...
};
如果你不想使用继承,你可以在每种类型的实体中都有一个成员变量的公共初始子序列,比如:
struct Unit {
EntityType type;
// ...
};
就内存布局而言,这相当于继承版本,您可以从selectEntity()
返回EntityType*,它实际上将指向Unit或Tree的第一个成员。