我正在用Java编写游戏,其中每个Entity
都可以有一个附加的EntityComponents
列表。例如,可以被杀死的Entities
(例如Player
)将具有Health
组件。检查玩家的健康状况如下:
int health = ((Health) player.getComponent(Health.KEY)).getValue();
我提出了一个轻微的快捷方式,其中每个EntityComponent
都包含一个静态get
方法,该方法使用适当的密钥调用实体的getComponent
方法。现在检查玩家的健康状况如下:
int health = Health.of(player).getValue();
这是一个既定的设计模式吗?如果是这样,这是什么?它看起来是个好主意(本质上是一个稍微缩短代码的附加方法调用)吗?是否有更好的方法来实现我想要做的事情?
修改
一些澄清,这里......
Health
包含getValue
,setValue
,modValue
,isDead
等方法。Health.of(entity)
只需致电entity.getComponent(KEY)
,其中KEY
是Health
类中的字段。Health.of
和Health.getValue
以前分别称为Health.get
和Health.getHealth
,但根据评论进行了更改。Entity
都是可以杀戮的 - 也就是说,不是每个Entity
都可以
有健康。因此,为每个getHealth
添加Entity
方法会
不行。Killable
方法的getHealth
界面也不是
理想的,因为这需要每个可用的Entity
复制相同的健康相关代码。Health
组件是a
故意为了将所有共享代码提取到一个共同的
位置。KillableEntity
也不是一个可行的解决方案,因为Health
是许多可能的组件之一,定义一个适应所有可能组合的继承结构是不切实际的(甚至可能是不可能的)。答案 0 :(得分:1)
这是一个既定的设计模式吗?不,我会把它描述为一种反模式。
int health = Health.get(player).getHealth();
在这里,你要求Health获得玩家,然后要求玩家获得健康,这可能会导致混乱。
根据我的理解,你似乎赞成合成而不是继承。鉴于此,这样的事情可能更有意义,
int health = player.getComponentIntValue(Health.KEY);
你也可以考虑让玩家实现HasHealth接口,而不是将其简化为:
int health = player.getHealth();
答案 1 :(得分:1)
这不是答案,但我认为它会有用。
考虑使用default
方法直接访问Health
的成员:
public interface HealthComponent extends Health {
Health healthComponent();
default int currentHealth() {
this.healthComponent().currentHealth();
}
}
现在,如果Player
实施Health
,HealthComponent
和healthComponent
方法,您可以执行以下操作:
Player player = new Player();
player.currentHealth();
它更简洁。此模式模拟Scala的traits。
一些澄清:
public interface Health {
int currentHealth();
void adjustHealth(int amount);
boolean isDead();
}
public final class DefaultHealth implements Health {
private int currentHealth;
public DefaultHealth(final int startingHealth) {
super();
currentHealth = startingHealth;
}
public int currentHealth() {
return currentHealth;
}
public void adjustHealth(final int amount) {
if (isDead()) {
return;
}
currentHealth += amount;
if (currentHealth < 0) {
currentHealth = 0;
}
}
public boolean isDead() {
return currentHealth > 0;
}
}
public class Player implements HealthComponent {
private final Health health;
public Player(final Health health) {
super();
this.health = health;
}
public Health healthComponent() {
return health;
}
}
免责声明:此代码是在浏览器中编写的;它可能无法编译。
答案 2 :(得分:0)
如果您在getComponent方法背后有任何特定原因,则可以直接执行不需要添加player.getComponent方法。
int health = player.getHealth(Health.KEY);
玩家是父亲的恩赐,玩家有健康成分所以getHealth方法应该是玩家对象而不是像这样的
int health = Health.get(player).getHealth();
答案 3 :(得分:0)
对于这个问题,我似乎可以从以下解决方案中选择一个:
从Entity派生Player类并为Entity类实现getHealth()方法
使Entity成为一个需要getHealth()方法的接口,并在Player类中实现该方法,在本例中它实现了Entity接口。
答案 4 :(得分:0)
它就像:
获得玩家的健康,或获得玩家的健康
我个人喜欢第一种方式。使用静态方法对于具有原始参数但没有内置上下文的方法(对于例如程序范例中的函数,例如Math.abs(int x)
)可能更好。
在您的情况下,健康是玩家的财产
答案 5 :(得分:0)
没有3个课程会更容易吗?
public abstract class Person {
}
public class Mortal extends Person {
//int health;
//setHealth(); getHealth{}; modHealth{};
//mortal(int health)
}
public class Immortal extends Person {}
然后,简单地说,
Person mortalPlayer = new Mortal(100);
mortalPlayer.getHealth();
答案 6 :(得分:0)
对我来说,这似乎是过度工程。
player.getComponent(Health.KEY)).getValue();
component
的含义是什么?它很可能是一些不属于玩家的人为概念。球员有健康。玩家没有组件。
最可能是最简单的解决方案
player.getHealth();
会更好。