有很多方法可以或多或少地完成您正在寻找的事情......我不熟悉“实体组件系统”或 Unity,但我构建了一个可能适合您需求的示例。
它以 Component 类型开始,我为此创建了一个空接口,但您可以将其设为抽象类或任何适合您需要的类型:
public interface Component {
}
我添加的下一个类是ComponentFactory
. 一个 ComponentFactory 创建一个固定类型的组件对象,给定一些参数。
public interface ComponentFactory<IN, T extends Component> {
Class<T> getComponentClass();
T createComponent(IN input);
}
下一个类是Lazy
,它只是添加了对 Lazy 的支持,但只对任何东西进行一次初始化。我稍后会使用它。
public static class Lazy<T> {
private volatile T value;
private final Supplier<? extends T> supplier;
public Lazy(Supplier<? extends T> supplier) {
this.supplier = supplier;
}
public T getValue() {
if (this.value == null) {
synchronized (this) {
if (this.value == null) {
this.value = this.supplier.get();
}
}
}
return this.value;
}
}
下一节课是Entity
。Entity 是您似乎已经拥有的类之一,但您遇到了困难,因为 Entity 需要将其组件传递给构造函数,但组件还需要在构造函数中传递的 Entity。实体现在不会接收在其构造函数中传递的组件,而是它可能在以后用于构造实际组件的工厂。
public static class Entity {
private final Map<Class<? extends Component>, Lazy<Component>> components;
public Entity(List<ComponentFactory<? super Entity, ?>> componentFactories) {
// do all of the basic construction
final Map<Class<? extends Component>, Lazy<Component>> components = new HashMap<>();
for (ComponentFactory<? super Entity, ?> factory : componentFactories) {
components.put(factory.getComponentClass(), new Lazy<>(() -> factory.createComponent(this)));
}
this.components = Collections.unmodifiableMap(components);
}
public <T extends Component> T getComponent(Class<T> componentClass) {
final Lazy<Component> lazy = this.components.get(componentClass);
final T component;
if (lazy != null) {
component = componentClass.cast(lazy.getValue());
} else {
component = null;
}
return component;
}
}
例子
作为一个例子,我创建了两个类“TransformComponent”,它接受一个实体和“PhysicsComponent”,它接受一个实体并使用该实体接收给定实体的TransformComponent。
public static class PhysicsComponent implements Component {
public static final ComponentFactory<Entity, PhysicsComponent> FACTORY = new ComponentFactory<>() {
@Override
public Class<PhysicsComponent> getComponentClass() {
return PhysicsComponent.class;
}
@Override
public PhysicsComponent createComponent(Entity input) {
return new PhysicsComponent(input);
}
};
private final TransformComponent tf;
public PhysicsComponent(Entity player) {
this.tf = player.getComponent(TransformComponent.class);
}
}
public static class TransformComponent implements Component {
public static final ComponentFactory<Entity, TransformComponent> FACTORY = new ComponentFactory<>() {
@Override
public Class<TransformComponent> getComponentClass() {
return TransformComponent.class;
}
@Override
public TransformComponent createComponent(Entity input) {
return new TransformComponent(input);
}
};
public TransformComponent(Entity player) {
}
}
请注意,两个 Component-Implementation 都有自己的工厂的公共静态最终变量。
最后,我们可以创建我们的玩家实体:
public static void example() {
final Entity player = new Entity(List.of(TransformComponent.FACTORY, PhysicsComponent.FACTORY));
final PhysicsComponent physicsComponent = player.getComponent(PhysicsComponent.class);
}