1
\$\begingroup\$

Currently I'm working with LibGDX and using Ashley for ECS. Everything is fine, until i need to remove groups of related components.

Say we have a player that may use different weapons. For now, in my game a weapon is described by one or more components.

For example we have weapons, each is described by its own components:

weapon1: [ c0, c1, c2 ];
weapon2: [ c3, c4 ];
weapon3: [ c5, c6, c7 ];

It's ok when I want to add a weapon. I know which components are required and can put them to entity. The issue comes when I need to replace one weapon with another.

I can deal with if-else when it's only 3-5 weapons. But what if there are 20?

For now, my idea is to have additional component called WeaponComponent. Which will contain a family (I mean Ashley Family instance) that contains all information i need to remove the unnecessary components. But for me it looks more like a workaround, not a solution.

So, does anybody know how to deal with this? Are there any other approaches?

UPDATE

OK, For now I have tried few implementations. And here is the one that seems to be the best for me. I have combined object-oriented and entity-component designes. The WeaponComponent holds a reference to a Weapon implementation. The Weapon implementations know exaclty which components to attach/remove to/from an entity.

interface Weapon {
    void attachTo(Entity entity);
    void removeFrom(Entity entity);
}
class WeaponComponent {
    private Entity owner;
    private Weapon weapon;
    public void setWeapon(Weapon weapon) {
        if(this.weapon != null)
            this.weapon.removeFrom(owner);
        if(weapon != null) {
            this.weapon = weapon;
            this.weapon.attachTo(owner);
        }
    }
}

So, using this design, changing weapons is very easy now. And I don't have to care what weapon is already attached, and how to remove it: engity.getComponent(WeaponComponent.class).setWeapon(whatEver);.

\$\endgroup\$
  • \$\begingroup\$ What's the paremeter/check you use to decide which weapon you want to replace? \$\endgroup\$ – jjimenezg93 Sep 6 '17 at 3:47
  • \$\begingroup\$ @jjimenezg93 well, for now I can check which weapon's components are in the player entity. But I need to check for all of the possible weapons to know which one to remove \$\endgroup\$ – lowercase93 Sep 6 '17 at 19:36
  • \$\begingroup\$ Instead of adding the solution you use in the question, you should add it as an answers; that's typically where visitors look for solutions (it's perfectly acceptable to post answers to your own question). \$\endgroup\$ – Vaillancourt Sep 30 '17 at 10:12
0
\$\begingroup\$

You can add an enum for the type of component, and add a type attribute to the Component base class.

...
enum EComponentType {
...
    ECT_Weapon,
...
}
...
class Component {
...
    EComponentType _type;

public:
    EComponentType getType() const;
... 
}

Then, you just need to check that attribute

if (component->getType() == EComponentType::ECT_Weapon) {
    entity->remove(component);
}

I have no idea about LibGDX but hope this helps.

\$\endgroup\$
  • 1
    \$\begingroup\$ Yeah, I think this one I will use. But instead of enum, i will use LibGDX's Family matcher, that allows to match several component classes at once. \$\endgroup\$ – lowercase93 Sep 9 '17 at 11:00
  • \$\begingroup\$ As I said, I have no idea about LibGDX :D but it seems basically the same idea. Glad it helped! \$\endgroup\$ – jjimenezg93 Sep 9 '17 at 11:19
0
\$\begingroup\$

If the weapon entity only contains weapon components you could just drop all components using

entity.removeAll();

Or drop the entity from the engine completely and remake with the new components.

Using the remove method to remove component will return null if a component doesn't exists so won't cause any issues if you want to try and remove all weapon components.

entity.remove(component.class);
\$\endgroup\$
  • \$\begingroup\$ Actually my player entity 'architecture' is made so that it contains about 10 components, and few of them describe weapon. Player also has transformation, input processing, texture, collider box, health, score an so on. I can not just remove all components, or remove the whole entity. \$\endgroup\$ – lowercase93 Sep 6 '17 at 19:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.