在为游戏编写简单的技能系统时,我遇到了一个小问题。我的系统基本约定使用注释来定义技能或能力是否满足所有预定义的要求,但我希望它是可扩展的。
为此,我实现了一个带有接口的 Enum 类,并对其中的 Enum 进行了注释以收集基本信息。我发现这限制了我创建另一个注释的能力,该注释可以放在其他类上,以查看是否需要“训练”该技能。
就像是:
public enum AthleticSkills implements AnnotatedSkill {
@Skill(name = "Jump", base = Agility.class, trained = true)
JUMP(public void use(){})
}
这个枚举可以是任意数量的技能类型,例如StrengthSkills等,都与AnnotatedSkill接口,这让我可以在方法和参数中定义AnnoatedSkill的类型,但我想做一些类似的事情:
public @interface TrainedSkill {
AnnotatedSkill[] value();
}
训练有素的技能保存在Set<AnnotatedSkill>
.
我知道这是不可能的,但我想坚持我设置的约定。如有必要,我愿意重新定义我如何设置技能,但如果有人有任何方法可以使这项工作保持与此相似,我将非常感激。
关于如何使用它的更多解释:
技能很简单,每个人都会拥有它们(想想旧的DND技能)并且每个人都可以使用它们,他们使用属性类(Agility.class,Strength.class等)来调整它们的效果。除此之外,还有能力训练一项技能,一次射击,你知道与否,这被添加到Set<AnnotatedSkill>
玩家对象中,这只是意味着你在使用该技能时会获得额外的修饰符。
ENUM中的use()方法可以根据注解中是否设置trained修饰符来使用,如果为true,则只有在skill被训练的情况下才能使用,如果为false,任何人都可以使用。
如果您希望限制谁可以训练技能(@Requirements)可以将训练/使用限制为类/种族/等,还可以添加另一个注释
我认为这将更多地属于技能/课程/种族/等的框架。
假设如下:
@Types(types = {EffectTypes.BUFF, EffectTypes.HEALTH, EffectTypes.HEAL})
@Requirements(
abilities = {
@RequireAbility(required = TimedHealAbility.class)})
@TrainedSkill(AthleticSkills.JUMP)
public class TimedHealEffect extends EffectComponent {}
只有当他们训练了 AthleticSkills.JUMP 并且满足@requirements 的要求时,才会出现这种效果。
跟踪训练的技能:
public class SkillTracking {
private Set<AnnotatedSkill> trainedSkills = Collections.newSetFromMap(new ConcurrentHashMap<AnnotatedSkill, Boolean>());
public void addSkill(AnnotatedSkill skill) {
trainedSkills.add(skill);
}
public boolean removeSkill(AnnotatedSkill skill) {
return trainedSkills.remove(skill);
}
public boolean hasSkill(AnnotatedSkill skill) {
return trainedSkills.contains(skill);
}
}