0

I am new to Artemis Entity Systems framework, and I want to know whether there is a way to get all the entities that have a specific component or components in them? (There should be, but I cannot find.)

For example I want to find all entities that have a EnemyComponent and check if they collide with any of the entities that have BulletComponent in them. How can I do this?

Narek
  • 38,779
  • 79
  • 233
  • 389
  • Upcoming artemis-odb version 0.10.0 supports retrieving a view of all entities belonging to an aspect. Until then use a manager or ES to track entities. EntitySystem#getActives works too. – junkdog Apr 16 '15 at 10:56

2 Answers2

1

What you can do is to create a system which will be called in your collision system to get the list of all entities with chosen components.

For example:

public class FindBulletsSystem extends EntitySystem {
  private ImmutableBag<Entity> bullets;
  private boolean processingFlag = false;

  public FindBulletsSystem () {
    super(Aspect.getAspectForAll(BulletComponent.class));

  }

  @Override
  protected boolean checkProcessing() {
    if (processingFlag) {
      processingFlag = false;
      return true;
    }
    return false;
  }

  @Override
  protected void processEntities(ImmutableBag<Entity> entities) {
         bullets = entities;

  }

  public ImmutableBag<Entity> getAllBullets() {
    bullets = null;
    processingFlag = true;

    this.process();
    return bullets;
  }

}

In your collision system you can get bullets by calling this system:

world.getSystem(FindBulletsSystem.class).getAllBullets();
Suwer
  • 260
  • 3
  • 10
  • 2
    This is a nice solution in frameworks of the API Artemis provides. But I think the right thing to do in this case is to use groups. I have seen several demos doing this: https://code.google.com/p/gamadu-starwarrior/source/browse/src/com/gamadu/starwarrior/systems/CollisionSystem.java What you think about this? – Narek Mar 03 '14 at 13:07
  • I think it depends on your need. I wouldn't go for groups in case I would have to check the collision against enemy, wall, tree, window and every object in game. In this case probably I would create a Component which would tell me that the object can be hit. In your case with only Enemy/Bullet collision group seems to be a good solution. – Suwer Mar 03 '14 at 13:34
  • In that case I have to create this kind of auxiliary Systems, which is not a convenient solution. Unfortunately, framework does not support the necessary functionality. – Narek Mar 03 '14 at 13:57
  • I think this is the idea, to make systems able to communicate with each other: "Entities or components do not communicate between themselves, but systems can communicate with other systems. You can retrieve other systems within your system by using the World instance. You can define whatever methods you deem necessery for inter-system communication." – Suwer Mar 03 '14 at 14:04
  • BTW another question: when you define `protected boolean checkProcessing()` function you don't have to call `findBulletsSystem->process()` any more? Where `checkProcessing` is being used? – Narek Mar 03 '14 at 14:38
  • 1
    findBulletSystem->process() is called in the getAllBullets() method. checkProcessing() is being used inside the process() method and if it returns false processEntities method wouldn't be called. – Suwer Mar 03 '14 at 14:58
1

Perhaps I was too strict in forbidding you from retrieving components by their type from the component manager, but I'm sure it was for a good reason at the time, enforcing a strict api.

The problem with "BulletComponent" and "EnemyComponent" is that they are flags, to indicate the type of group they belong to. Do they contain any data? What if you had a FlagSystem that processes FlagComponent, which has an array of flags. You could request from this flagSystem entities having certain flags.

But there's no one way to do this. You could create your own Manager class, or you could do this with systems.

Arni Arent
  • 11
  • 1