EntitätComponentenModell - Robust-Games/robust GitHub Wiki

Was ist eine Entity?

Eine Entity enthält selbst keine Logik. Es werden verschiedene Eigenschaften (Components) angehängt.

  • City, Shell, Mountain, Tile sind spezialisierte Entities mit eigenen Data-/Animation-Components.
  • Selection & Hover sind Hilfs-Entities zur Markierung/Animation. esc.png
  • Tank ist die umfangreichste Entität tank.png
Entity tank = FXGL.entityBuilder()
    .type(EntityType.TANK)
    .with(new IDComponent(IDFactory.generateId()))
    .with(new TankDataComponent(Player.PLAYER1, tankTexture))
    .buildAndAttach();

Was ist ein Component?

Ein Component ist ein Daten- oder Verhaltens-Baustein, der an Entities angehängt wird.

  • Kann dynamisch zur Laufzeit hinzugefügt oder entfernt werden.
  • Komponenten definieren den Zustand einer Entity.

Beispiele aus dem Projekt:

  • TankDataComponent: Speichert Texturen, Spielerzuordnung und Position.
  • MovementComponent: Erzeugt mögliche Bewegungspfade.
  • ShootComponent: Kümmert sich um die Zielauswahl beim Schießen.
  • AnimExplosionComponent: Spielt eine Explosion ab.
public class IDComponent extends Component {
    private final long id;

    public IDComponent(long id) {
        this.id = id;
    }

    public long getId() {
        return id;
    }
}

Wie hängt man Components an?

Entity tank = FXGL.entityBuilder()
    .type(EntityType.TANK)
    .with(new IDComponent(IDFactory.generateId()))
    .with(new TankDataComponent(Player.PLAYER1, tankTexture))
    .with(new SelectableComponent())
    .buildAndAttach();

Components können auch zur Laufzeit hinzugefügt oder entfernt werden:

tank.addComponent(new MovementComponent());
tank.removeComponent(MovementComponent.class);

Was sind Actions?

Actions sind Abläufe, die eine Entity über Zeit ausführt. Sie werden von FXGLs ActionComponent verwaltet.

Beispiele:

  • MovementAction: Tank bewegt sich zu einem Ziel.
  • RotateAction: Tank ändert seine Ausrichtung.
  • ShootAction: Tank schießt auf ein Ziel.
ActionComponent ac = tank.getComponent(ActionComponent.class);
ac.addAction(new MovementAction(targetEntity));

Was sind Services?

Services sind Spiel-Logik-Einheiten, die Daten aus Components verarbeiten. Sie interpretieren die Daten und führen die Logik aus.

  • Beispiel: MovementService berechnet gültige Bewegungspfade.
  • Beispiel: RotateService dreht den Panzer und berechnet die richtige Textur.
  • Beispiel: ShootService führt Schüsse aus und reduziert HP.

Was sind Factories?

Factories sind Baupläne für Entities.

  • Sie erzeugen Objekte mit den richtigen Components.
  • Beispiel: PlayerFactory erstellt Tanks und weist sie Spielern zu.
  • Beispiel: MapFactory baut die Karte mit Bergen, Städten, Tiles.
public class PlayerFactory implements EntityFactory {
    @Spawns("Tank")
    public Entity newTank(SpawnData data) {
        return FXGL.entityBuilder(data)
            .type(EntityType.TANK)
            .with(new IDComponent(IDFactory.generateId()))
            .with(new TankDataComponent((Player)data.get("owner"), data.get("texture")))
            .build();
    }
}

Warum dieses Modell?

  • Komposition statt Vererbung → flexibel, erweiterbar.
  • Saubere Trennung von Daten und Logik.
  • Mehr Performance (cache-friendly, ECS ist für Spiele optimiert).
  • Testbar: Components speichern nur Daten, Services enthalten die Logik.

Übersicht

  • Entity: Leere Hülle, eindeutige ID.
  • Component: Zustand/Daten einer Entity.
  • Service: Verarbeitet Logik basierend auf Components.
  • Action: Zeitlicher Ablauf für Entities.
  • Factory: Erzeugt Entities mit den richtigen Components.

Zusammenspiel: Entities bekommen Components, Factories bauen sie, Services verarbeiten sie, Actions führen sie aus.