详细说明我的问题,具体情况如下:
如果我有一个模拟或游戏项目,例如,Monster
类具有不同的统计数据作为成员数据(hitPointsRemaining
,AttackDamage
等),我想拥有任何具有常数基数统计数据的不同类型的怪物数量(MaxHP
,Speed
等),然后我看到了这个类需要使用的三种方式:
Monster
”)Monster
个对象,代表不同的怪物,因为角色在游戏中遇到它们(可能随时有多个相同类型的实例)我想知道大多数设计师是如何实现这一目标的。 我的想法如下:
- 制作一个Monster
类然后为每个类型的怪物创建一个新的子类是没有意义的。这似乎是一个非常混乱和不可维护的解决方案,特别是如果不同的怪物类型的数量变化数百,并且每种类型之间的差异不足以保证新的子类
-Rather,我的解决方案如下:
1.拥有一个文件,可以添加到包含表中所有不同Monster
类型及其特征的数据。该表可以在项目开发的任何时候添加。
编写一个函数,将表中的数据加载到Monster
对象中。
在程序开头写一个初始化调用,可能在某种MonsterManager
类中,解析文件并创建一个实例化Monster
对象的静态或成员向量从文件中的表格填写的“基础”统计数据(即起始点等)
每当我想要实例化某种类型的新Monster
以添加到某人的军队或让某人遇到某人时,请从该向量中选择Monster
(随机或通过一些确定的因素) )创建一个新的Monster
对象,并将其从向量中复制出来
这是一种解决方案还是我出去吃午饭?如果这不是一个好的解决方案,那么有哪些更好的方法?
其他补充问题:
- 为向量中保存的怪物数据创建不同的类是否有意义?我以为我可以有一个名为MonsterData
的类,它将被上面的MonsterManager
构建到一个向量中。我可以将MonsterData
对象传递给Monster
类的构造函数来实际创建Monster
个对象,因为很多Monster
个对象的特征将由他们的怪物决定-types(MaxHP,速度等)和其他东西会有所不同(CurrentHP,任何随机变量等)
- 我认为这个方法是可以优化的,因为你可以做一些事情,比如在表格中添加一个条目,指出怪物出现在哪个级别,然后让MonsterManager
初始化函数只加载某些级别的所有怪物立刻缩小内存占用量)
- 既然我没有使用enum
,那么存储文本字符串是否有意义来识别Monster
对象的“类型”?也许从Monster
的向量中复制它的MonsterData
(或MonsterManager
)的指针会更好吗?
我使用游戏比喻,因为这是我在这里最有意义的,但我想知道在任何情况下这种事情的最佳设计模式。
谢谢大家!
答案 0 :(得分:4)
继承应该用于修改/添加行为,而不是用于变化的数据值。在您的示例中,似乎每个怪物都由一组属性(HP,攻击等)定义,并且您希望在游戏中实例化不同的怪物类型。你真的不需要继承。
您与MonsterData
班级走在正确的轨道上;这是我将如何去做(大多数只是我认为更有意义的类的不同名称):
// This is what you called MonsterData
// It describes how to create a monster of a specific type
public class MonsterDescription {
private String type; // eg. "Goblin"
private int maxHitPoints;
private int speed;
...
}
// This is an "active" instance of a monster
public class Monster {
private int currentHitPoints;
...
// static factory method
public static Monster create(MonsterDescription desc) {
...
}
}
// This is kind of what you called MonsterManager
// Contains a collection of MonsterDescription, loaded from somewhere
public class MonsterDescriptionRepository {
// finds the description for a given type of monster
public MonsterDescription find(String type) {
...
}
}
接下来是你如何实例化一个新怪物:
MonsterDescription desc = repository.find("Goblin");
Monster monster = Monster.create(desc);
答案 1 :(得分:2)
dataloader方法似乎适合您的问题 - 它使其易于扩展。 我建议创建不同功能的子类 - 例如,创建一个FlyingMonster子类,它将处理Dragon而不是Goblin或Shark 通过这种方式,您可以(尝试)避免使用可以飞行/跑/潜水的单个怪物类;)
你的最后一个问题是关于外部数据键控 - 为此我认为指针方法是最好的:
注意:我不认为你应该“关心”任何性能问题(将它们加载到内存中以减少内存占用),因为它通常会破坏设计