Java 游戏设计 Class 加载中
Java Game Design Class Loading
我正在使用 JavaFX 构建 RPG,需要从专家那里获得一些建议。
加载某些资源的正确方法是什么?我不是在谈论图像和声音,那部分很简单。我说的是 classes。例如;我有一些奇怪的 400 多种你可以激活的能力。我为每种能力(或我所说的 arte)分别设置了 class。要访问此功能,我希望能够调用
Data.getArte(idOfArte);
这应该 return 一个 Arte 类型的对象。所有艺术都有一个单独的 class 文件。
还有其他资源也是如此,例如英雄、敌人等。加载和调用这些资源以供使用的最佳方式是什么?有更好的方法吗?
编辑:我也很关心性能。
您正在寻找工厂模式。我在这里找到了一篇关于它的好文章:http://alvinalexander.com/java/java-factory-pattern-example
我假设您不必在运行时旁加载 class 文件?如果是这种情况,我建议您在这里查看:Method to dynamically load java class files
一种更有效的方法可能是使用 Entity Component System 或至少借用构图设计。这允许你有一个单一的具体 class,比如 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 classes,而你的 400 个能力只是成为基本通用能力的配置。举个例子,这里有一个 RPG 大约有 100 种能力(技能),它们被实现为 6 classes。同样的设计也可以用于任何游戏物品/角色。
至于对象创建你可以这样做:
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();
或者,使数据存储 return 成为已克隆的能力,这样您就不会暴露原型。
最后,你可以考虑使用脚本语言,例如java脚本,改变通用能力的行为。在这种情况下,您的所有能力都将存储在一个文件夹 scripts/abilities/
中,您可以在运行时加载该文件夹,并且只加载您需要的那些。一些任意示例:(heal.js 文件)
function onUse(object, healValue) {
if (object.hasComponent(HP_COMPONENT)) {
val hp = object.getComponent(HP_COMPONENT);
hp.value += healValue;
}
}
这里有一个 article,显示了如何在 java 中调用 java 脚本函数。
我正在使用 JavaFX 构建 RPG,需要从专家那里获得一些建议。
加载某些资源的正确方法是什么?我不是在谈论图像和声音,那部分很简单。我说的是 classes。例如;我有一些奇怪的 400 多种你可以激活的能力。我为每种能力(或我所说的 arte)分别设置了 class。要访问此功能,我希望能够调用
Data.getArte(idOfArte);
这应该 return 一个 Arte 类型的对象。所有艺术都有一个单独的 class 文件。
还有其他资源也是如此,例如英雄、敌人等。加载和调用这些资源以供使用的最佳方式是什么?有更好的方法吗?
编辑:我也很关心性能。
您正在寻找工厂模式。我在这里找到了一篇关于它的好文章:http://alvinalexander.com/java/java-factory-pattern-example
我假设您不必在运行时旁加载 class 文件?如果是这种情况,我建议您在这里查看:Method to dynamically load java class files
一种更有效的方法可能是使用 Entity Component System 或至少借用构图设计。这允许你有一个单一的具体 class,比如 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 classes,而你的 400 个能力只是成为基本通用能力的配置。举个例子,这里有一个 RPG 大约有 100 种能力(技能),它们被实现为 6 classes。同样的设计也可以用于任何游戏物品/角色。
至于对象创建你可以这样做:
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();
或者,使数据存储 return 成为已克隆的能力,这样您就不会暴露原型。
最后,你可以考虑使用脚本语言,例如java脚本,改变通用能力的行为。在这种情况下,您的所有能力都将存储在一个文件夹 scripts/abilities/
中,您可以在运行时加载该文件夹,并且只加载您需要的那些。一些任意示例:(heal.js 文件)
function onUse(object, healValue) {
if (object.hasComponent(HP_COMPONENT)) {
val hp = object.getComponent(HP_COMPONENT);
hp.value += healValue;
}
}
这里有一个 article,显示了如何在 java 中调用 java 脚本函数。