枚举是在 Roguelike 游戏中生成生物的正确工具吗?
Is enumeration the right tool for generating creatures in a roguelike game?
我正在开发一款类似 roguelike 的游戏,作为 programming/database 练习和爱好(因为我想拥有自己的 "Dwarf Fortress" 项目,任我支配)。在尝试编写一个足够强大的系统来在游戏中生成各种生物时,我很早就陷入困境。我开始很简单;假设我想让游戏在某个地方吐出一只狼(FXML,所以控制器):
public class Controller {
Creature pooch = new Creature(Species.WOLF);
}
现在,我希望能够通过仅指定它们的种类来生成这些普通动物,所以这就是枚举的目的,不是吗?我想说明狼只吃肉,它们可能的 body 大小(它们毕竟不是克隆,还有什么地方可以指定大小?),以及它们的 body 类型:
public enum Species {
// Canines
WOLF(Diet.CARNIVORE, 1050, 1325, 1600, CANINE.BodyPattern);
// Canine constructor
Species(Diet diet, double bodySizeMultiplierMin, double bodySizeMultiplierAvg, double bodySizeMultiplierMax,
BodyPattern bodyPattern) {
this.diet = diet;
this.bodySizeMultiplierMin = bodySizeMultiplierMin;
this.bodySizeMultiplierAvg = bodySizeMultiplierAvg;
this.bodySizeMultiplierMax = bodySizeMultiplierMax;
}
我想为狗、豺等重用相同的模式,所以我只传递 body 类型,在另一个枚举中定义。
enum BodyPattern {
CANINE(furryUpperBody, furryLowerBody, canineHead, canineMaw, canineLegs, furryTail);
LinkedList<BodyPart> bodyPartsList;
BodyPattern(BodyPart... args) {
for (BodyPart part : args) {
bodyPartsList.add(part);
}
}
}
这是我真正迷路的地方(我实际上并没有定义任何 body 部分,因为我不确定如何继续)。到目前为止,这是我对 BodyPart 的看法:
public class BodyPart {
public String name;
private TissueLayer[] tissueLayersUp;
private TissueLayer[] tissueLayersDown;
private TissueLayer[] tissueLayersFront;
private TissueLayer[] tissueLayersBack;
private TissueLayer[] tissueLayersLeft;
private TissueLayer[] tissueLayersRight;
public BodyPart(String name, BodyPart[] appendages, int height, int width, int length, TissueLayer[] tissueLayersUp,
TissueLayer[] tissueLayersDown, TissueLayer[] tissueLayersFront, TissueLayer[] tissueLayersBack,
TissueLayer[] tissueLayersLeft, TissueLayer[] tissueLayersRight) {
this.name = name;
this.appendages = appendages;
this.height = height;
this.width = width;
this.length = length;
this.tissueLayersUp = tissueLayersUp;
this.tissueLayersDown = tissueLayersDown;
this.tissueLayersFront = tissueLayersFront;
this.tissueLayersBack = tissueLayersBack;
this.tissueLayersLeft = tissueLayersLeft;
this.tissueLayersRight = tissueLayersRight;
}
}
组织层是构成 body 部分的材料,并且分别为每个方向指定,例如对头部正面的攻击会损坏面部,而从背面进行的攻击首先反对 neck/upper 脊柱。我希望它们的厚度仅以相对术语定义,在生成时乘以生物的大小以生成实际大小,但正如我所说,我有点迷路了,那么我该从哪里开始呢?我应该将 BodyPart 重新分配为枚举吗?我应该完全制作另一个枚举吗?我完全偏离轨道了吗?我应该使用其他工具吗?
Now, I'd like to be able to spawn these ordinary animals by only
specifying their species, so that's what enumerations are for, no?
恐怕没有,没有。
枚举的最佳用例是枚举一组对象,这些对象是常量并且所有这些对象的标识在编译时都是已知的。枚举是理想数据的一个例子是扑克牌或太阳系的行星。扑克牌的花色和数字是固定的、不变的,并且是预先知道的。同样,太阳系中的行星也不会(经常)发生变化。
由于您希望能够在需要时动态创建对象,因此您会希望在程序需要时使用带有构造函数的普通 类 来创建新对象(例如动物)。很难想象一款游戏可以预先知道它需要的所有动物(及其所有属性)。
我正在开发一款类似 roguelike 的游戏,作为 programming/database 练习和爱好(因为我想拥有自己的 "Dwarf Fortress" 项目,任我支配)。在尝试编写一个足够强大的系统来在游戏中生成各种生物时,我很早就陷入困境。我开始很简单;假设我想让游戏在某个地方吐出一只狼(FXML,所以控制器):
public class Controller {
Creature pooch = new Creature(Species.WOLF);
}
现在,我希望能够通过仅指定它们的种类来生成这些普通动物,所以这就是枚举的目的,不是吗?我想说明狼只吃肉,它们可能的 body 大小(它们毕竟不是克隆,还有什么地方可以指定大小?),以及它们的 body 类型:
public enum Species {
// Canines
WOLF(Diet.CARNIVORE, 1050, 1325, 1600, CANINE.BodyPattern);
// Canine constructor
Species(Diet diet, double bodySizeMultiplierMin, double bodySizeMultiplierAvg, double bodySizeMultiplierMax,
BodyPattern bodyPattern) {
this.diet = diet;
this.bodySizeMultiplierMin = bodySizeMultiplierMin;
this.bodySizeMultiplierAvg = bodySizeMultiplierAvg;
this.bodySizeMultiplierMax = bodySizeMultiplierMax;
}
我想为狗、豺等重用相同的模式,所以我只传递 body 类型,在另一个枚举中定义。
enum BodyPattern {
CANINE(furryUpperBody, furryLowerBody, canineHead, canineMaw, canineLegs, furryTail);
LinkedList<BodyPart> bodyPartsList;
BodyPattern(BodyPart... args) {
for (BodyPart part : args) {
bodyPartsList.add(part);
}
}
}
这是我真正迷路的地方(我实际上并没有定义任何 body 部分,因为我不确定如何继续)。到目前为止,这是我对 BodyPart 的看法:
public class BodyPart {
public String name;
private TissueLayer[] tissueLayersUp;
private TissueLayer[] tissueLayersDown;
private TissueLayer[] tissueLayersFront;
private TissueLayer[] tissueLayersBack;
private TissueLayer[] tissueLayersLeft;
private TissueLayer[] tissueLayersRight;
public BodyPart(String name, BodyPart[] appendages, int height, int width, int length, TissueLayer[] tissueLayersUp,
TissueLayer[] tissueLayersDown, TissueLayer[] tissueLayersFront, TissueLayer[] tissueLayersBack,
TissueLayer[] tissueLayersLeft, TissueLayer[] tissueLayersRight) {
this.name = name;
this.appendages = appendages;
this.height = height;
this.width = width;
this.length = length;
this.tissueLayersUp = tissueLayersUp;
this.tissueLayersDown = tissueLayersDown;
this.tissueLayersFront = tissueLayersFront;
this.tissueLayersBack = tissueLayersBack;
this.tissueLayersLeft = tissueLayersLeft;
this.tissueLayersRight = tissueLayersRight;
}
}
组织层是构成 body 部分的材料,并且分别为每个方向指定,例如对头部正面的攻击会损坏面部,而从背面进行的攻击首先反对 neck/upper 脊柱。我希望它们的厚度仅以相对术语定义,在生成时乘以生物的大小以生成实际大小,但正如我所说,我有点迷路了,那么我该从哪里开始呢?我应该将 BodyPart 重新分配为枚举吗?我应该完全制作另一个枚举吗?我完全偏离轨道了吗?我应该使用其他工具吗?
Now, I'd like to be able to spawn these ordinary animals by only specifying their species, so that's what enumerations are for, no?
恐怕没有,没有。
枚举的最佳用例是枚举一组对象,这些对象是常量并且所有这些对象的标识在编译时都是已知的。枚举是理想数据的一个例子是扑克牌或太阳系的行星。扑克牌的花色和数字是固定的、不变的,并且是预先知道的。同样,太阳系中的行星也不会(经常)发生变化。
由于您希望能够在需要时动态创建对象,因此您会希望在程序需要时使用带有构造函数的普通 类 来创建新对象(例如动物)。很难想象一款游戏可以预先知道它需要的所有动物(及其所有属性)。