Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Jar

Treue Seele

  • »Jar« ist der Autor dieses Themas

Beiträge: 197

Wohnort: Lübeck

Beruf: Softwareentwickler

  • Private Nachricht senden

11

21.02.2017, 19:21

Die Entity mit TransitionComponent ist sogar schon umgesetzt :)

Die Umbauidee des MessageSystems ist ziemlich genial. Leider bietet Ashley nicht eine einfache Möglichkeit auf das Hinzufügen und Entfernen von Components zu reagieren.
Wurde auch schon öfters disskutiert: https://github.com/libgdx/ashley/issues/188

Man könnte jedoch die Messages auch als Entities sehen und ein System erstellen, welches auf erstellte bzw. gelöscht Entities mit einer MessageComponent reagieren.
Nur müsste ich dann in alle Systemen die Nachrichten schicken wollen meine Engine (das Hauptobjekt vom AshleyECS) speichern und immer eine Entity + Component erstellen.

Jar

Treue Seele

  • »Jar« ist der Autor dieses Themas

Beiträge: 197

Wohnort: Lübeck

Beruf: Softwareentwickler

  • Private Nachricht senden

12

27.02.2017, 14:57

Okay, also habe das MessageSystem jetzt mal so gelassen wie es war, nach einem kleinen Exkurs das mit Entities zu machen.
Ich betrachte Entities nun lieber so, das diese auch wirklich Dinge sind die für den Spieler sichtbar sind, oder ihn beeinflussen.

Anyway.
Meine Spieler Entity kann nun eine CurrentLocationComponent oder eine CurrentTransitionComponent haben.
Zwei Systeme kümmern sich dann anhand dieser Components um die Bewegung des Spielers.

Somit habe ich das MapSystem um die Infos der Spielerpositionen ausgedünnt.

Jetzt muss ich mir ein neues TODO suchen.

Renegade

Alter Hase

Beiträge: 494

Wohnort: Berlin

Beruf: Certified Unity Developer

  • Private Nachricht senden

13

08.03.2017, 17:25

Vielleicht etwas spät, aber dennoch interessant:
Es gibt von Entitas ECS (eigentlich für C#/Unity) eine Portierung für Java. Das Tolle: bei Entitas kannst du mittels reaktiver Systeme auf Komponenten add/remove hören. Vielleicht ist es für dich ein Blick wert (... auch wenn Ashley bei LibGDX mehr oder weniger dabei ist).
https://github.com/Rubentxu/Entitas-Java
Liebe Grüße,
René

Jar

Treue Seele

  • »Jar« ist der Autor dieses Themas

Beiträge: 197

Wohnort: Lübeck

Beruf: Softwareentwickler

  • Private Nachricht senden

14

10.03.2017, 09:24

Witzig!
Das hab ich gestern auch gerade enteckt.

Das Problem ist, das der Java Port irgendwie ziemlich dreckig ist. Das Projekt hat viele zusätzliche Dateien die nicht zuende programmiert wurden.
Und es gibt auch keine gute Erklärung und keinen einfachen Einstieg. Das C# Projekt ist dagegen sehr interessant.

Ich muss zugeben ECS bereitet mir manchmal schon ziemlich Kopfschmerzen weil ich grundsätzlich nicht genau weiß was hier best practice ist.
Nehmen wir mal ein einfaches Beispiel, ein 2D Rouge Like.

Sagen wir wir haben eine Raum 9 x 9, der von einer Mauer umgeben ist.
Im Raum befinden sich der Spieler und drei Gegner.
Jetzt soll sich der Spieler 3 Schritte bewegen können und danach sollen jeweils die Gegner sich nacheinander bewegen.

Wie modelliert man das, welche Systeme und Components braucht man?
Von der Eingabe der Tasten über das Entscheiden wer sich Bewegen soll, bis hin zum Ende einer Runde.
Ich habe dazu zwar schon etwas modelliert, aber bevor ich hier etwas vorweg nehmen hole ich mir lieber euren Rat ein.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Jar« (10.03.2017, 12:41)


Renegade

Alter Hase

Beiträge: 494

Wohnort: Berlin

Beruf: Certified Unity Developer

  • Private Nachricht senden

15

10.03.2017, 19:39

Für dein Rogue Beispiel könnte das grob so aussehen:

Components:
- MoveComponent (X/Y Koordinaten)
- TurnComponent (Ereignis, zeigt ob Entität am Zug ist)
- InputComponent (X/Y Koordinaten)
- TeamComponent (Zeigt Teams durch ID)

Systeme:
- InputSystem (Wenn Input kommt, ist er valide (auf Map etc.), erzeuge InputComponent auf Player)
- TurnSystem (Prüft ob InputComponent auf Entität valide ist, hat das Team aktuell die TurnComponent, dann erzeugt es MoveComponents)
- KISystem (Reagiert auf TurnComponent und feuert InputComponents auf die KI)
- MatchSystem (Steuert das aktuelle Match und vergibt TurnComponents an Spieler und KI bzw. abwechselnd an die Entitäten der Teams (TeamComponent))
- MoveSystem (bewegt eine Entität, wenn sie eine MoveComponent hat)

Hinzukommen können noch Prozess/Verarbeitungs/Umwandlungs Systeme um Daten zu verarbeiten. Beispielsweise ein InputProcessSystem, welches das Koordinatensystem der Kamera in das der Map umwandelt. Auch zur Verarbeitung bezüglich der Map wäre ein weiters System sinnvoll, welches prüft ob die MoveComponent valide ist (Anhand einer MapComponent).

Man kann hier noch viel mehr in's Detail gehen. Gerade das MatchSystem kann man noch deutlich weiter aufdrösseln.

Mein Ratschlag:
- Versuche die Komponenten und Systeme kurz und knapp zu halten.
- Ein System ist exakt nur für eine Aufgabe zuständig.
- Komponenten bestehen meist nur aus wenigen Datensätzen und sollten klar zu lesen sein.
- Scheue dich nicht vor vielen kleinen Klassen/Objekten.
- Überlege dir zuvor den Ablauf in Form von Ereignissen. So lassen sich wunderbar Komponenten ableiten und davon wiederum Systeme.
Liebe Grüße,
René

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »Renegade« (10.03.2017, 19:51)


Jar

Treue Seele

  • »Jar« ist der Autor dieses Themas

Beiträge: 197

Wohnort: Lübeck

Beruf: Softwareentwickler

  • Private Nachricht senden

16

10.03.2017, 20:54

Danke für deinen Beitrag.

Bei mir sieht das für das Beispiel ähnlich aus:

Components_
- MoveComponent(Direction)
- TurnComponent
...
- SpeedComponent ... TextureC. etc.

Systeme:
- InputSystem (Gibt MoveComponent an die Spieler Entity)
- MovementSystem (Berechnet anhand von MoveComponent und Speed die neue Positon)
- ReachedTargetSystem (Prüft ob das Ziel erreicht wurde und entfernt MoveComponent)
- WorldSystem (Hat Wissen über alle für den Spieler sichtbare Entities, "Tile"Entities, "Enemy"Entities.. usw, wird für Collisions-Abfragen benutzt.)

Kannst du mir die InputComponent genauer erklären.
Derzeit hatte ich im InputSystem Eingaben verarbeitet und durch einen MoveCommand eine MoveComponent an die Spieler Entity geschickt.

Übrigens habe ich gerade herausgefunden wie ich auf das Hinzufügen und das Löschen von Components via Listener reagieren kann. Ashley bietet das doch.
Da aber nicht sehr clean"code" verpackt kommt man nicht so einfach drauf.

Man kann ein EntityListener mit einer Family bei der Engine registrieren und es wird entityAdded oder entityRemoved auch geworfen wenn nur eine der Components aus der Family entfernt wird und dadurch die Family nicht mehr matched.
Da muss man erstmal drauf kommen. Für mich sieht das so aus, als würde hier nur auf das Hinzufügen und Löschen einer Entity aus der Engine reagiert werden.

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    private static final Family FAMILY = Family.all(
            WorldPositionComponent.class,
            MoveComponent.class).get();

//...
        engine.addEntityListener(FAMILY, new EntityListener() {
            @Override
            public void entityAdded(Entity entity) {
                System.out.println("added");
            }

            @Override
            public void entityRemoved(Entity entity) {
                System.out.println("removed");
            }
        });

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Jar« (10.03.2017, 21:45)


Werbeanzeige