更有效的方法可能是使用Entity Component System 或至少借用组合设计。这允许您拥有一个具体的类,比如Ability,它将包含所有能力共有的通用字段,例如技能点成本、能力持续时间、目标类型、激活类型等。然后,您将拥有一个用于您需要添加的每个特殊值的组件,以及一个用于您需要添加到该通用能力的每个特殊行为的控件。示例:
Ability ability = new Ability();
ability.addComponent(new DurationComponent(double seconds)); // specify how long effect lasts
ability.addControl(new DamagingControl(int damage, Object targetType, etc.)); // so ability can damage
ability.addControl(new ElementAugmentingControl(Element element, Object weapon/armor, etc.)); // so ability can change status effects / elements
这应该让您了解构图。根据你能力的共同行为,你最终应该有大约 10-30 个类,而你的 400 个能力只是成为基本通用能力的配置。举个例子,这里有一个 RPG,它有大约 100 种能力(技能),它们被实现为 6 个类。同样的设计也可以用于任何游戏物品/角色。
至于创建对象,您可以:
public static final int ABILITY_ID_SOME_NAME = 1000;
ability.addComponent(new IDComponent(ABILITY_ID_SOME_NAME));
那么您的每个能力都可以成为全局数据存储的一部分,其中仅存储能力原型:
Ability ability = DataStore.getByID(ABILITY_ID_SOME_NAME).clone();
或者,让数据存储返回一个已经克隆的能力,这样您就不会暴露原型。
最后,您可以考虑使用脚本语言,例如javascript,改变泛型能力的行为。在这种情况下,您的所有能力都将存储在一个文件夹 scripts/abilities/ 中,您在运行时加载该文件夹,并且只加载您需要的那些。一些随意的例子:(heal.js 文件)
function onUse(object, healValue) {
if (object.hasComponent(HP_COMPONENT)) {
val hp = object.getComponent(HP_COMPONENT);
hp.value += healValue;
}
}
这是一个article,它展示了如何在 java 中调用 javascript 函数。