组件架构:返回类型Superclass Ideal Solutions的子类

时间:2016-12-03 10:32:14

标签: java objective-c class types libgdx

我对java一般都很陌生,所以我一直在关注过多的教程。所以每次转动都要随意纠正我! (即使在代码效率低下也是如此!!)

我目前遇到的问题是从一个超类中获取一个返回不同子类/类型的方法。

问题代码位于帖子的底部。

准备好了,因为我要把它扔给你。

我遇到了 Java语言障碍

我正在关注tutorial(libGDX)使用 LibGDX 和其他教程来实现基于组件的设计(请参阅下面的链接)

我从未见过Objective-C代码,所以这些是我将tutorial code(component design)转换为java

的微弱尝试

目前的想法是让Entity使用各种Component来访问游戏中的不同功能(健康,渲染,移动等)。

我尝试将ComponentEntity相关联并检查其字段,但我在返回类类型方面遇到了某种问题。

组件系统

Component.java

public class Component {

}

HealthComponent.java

public class HealthComponent extends Component{
    public boolean alive;
}

RenderComponent.java

public class RenderComponent extends Component {
    public boolean canRender;
}


实体系统

我将EntityComponent s存储在可用活跃Component的列表(ArrayMap [LibGDX])中,以便我可以获得所有Entity个使用指定的Component。或者在这种情况下,获取与Component

相关联的特定Entity

Entity.java

public class Entity {
    private int eid;

    public Entity (int eid) {
        this.eid = eid;
    }

    public int eid () {
        return this.eid;
    }
}

EntityManager.java

public class EntityManager {
    public ArrayMap<String, ArrayMap<Integer, Component>> componentsByClass;
    // Some other stuff like constructors and methods
    public Component getComponentOfClassForEntity(Component component, Entity entity) {
        //returns Component type
        return componentsByClass.get(component.getClass().getSimpleName()).get(entity.eid());
    }
}

我的问题来到这个部分

我的理解是为了尽可能地保持DRY我不希望为每个Component子类提供多种不同的方法,只是为ExampleComponent返回不同的类类型。如果我可以通过某种类型/类更流畅的外部令人敬畏的东西顺利地工作将是非常方便的,没有任何疯狂的黑客行为是不好的做法。此外,我假设一些if / then语句可以起作用,但似乎有一种更好的方式,因为我的知识有限而且所有。

我试图:

Component health = this.entityManager.getComponentOfClassForEntity(healthComponent, entity);
// No errors, however I don't really have a health component now do I?...Trying out:
if((HealthComponent)health.alive) // Cannot resolve symbol "alive"...

或相同但改变类型:

HealthComponent health = this.entityManager.getComponentOfClassForEntity(healthComponent, entity);
// Required: HealthComponent
// Found: Component
// Sucks as I'd like to be able able to follow the DRY conventionthingy:
RenderComponent render = this.entityManager.getComponentOfClassForEntity(renderComponent, entity);
if(render.canRender))//plsssrenddrr
etc...

完全,我明白你不应该这样做,但我的问题是什么是一个理想的解决方案,不会破坏惯例或制作一个hacky和编码不佳的游戏。

也许有一个更好的基于组件的架构,这是一个更清洁,更可行的解决方案...

非常感谢!!

1 个答案:

答案 0 :(得分:0)

我建议你把DRY原则的逻辑结论和不要重复别人(如果有人可以把它变成一个时髦的首字母缩略词,然后让我知道)。

已经有一些很好的Java ECS库,我强烈建议你尝试使用(或扩展)其中一个,而不是创建自己的。坦率地说,如果你试图建立自己的ECS,你很可能永远不会完成游戏本身。

在众多可用的ECS中,我建议您从AshleyArtemis开始。

Ashley是一个轻量级ECS,似乎以某种方式与libGDX组相关联 - libGDX设置工具为您提供了将Ashley包含在它为您生成的gradle文件中的选项。在我看来,它有比我更喜欢的样板代码,但这也意味着它不会做更少的黑魔法(即反射)。

由于语法优势,我亲自转移到Artemis,它似乎进一步优化并更积极地维护。如果您想将其添加到游戏中,可以关注the instructions here

所有这些,这些都是伟大的图书馆,值得进行更深入的比较,只要您使用其中一个(或另一个ECS库),它应该可以让您实现目标。

现在,如果你对制作ECS比对游戏更感兴趣(而且我已经完全在那里),我仍然会建议你看看这两个库采用的方法(他们的代码在GitHub上)并看看他们如何处理语法问题。