# Hilfe bei Entities benötigt



## Lukas1995 (29. Sep 2012)

Hallo 

Wie der Titel schon sagt, brauche ich ein bißchen Hilfe beim Verständnis von Entities.

Ich benutze Slick 2D als Engine, ich komme auch ganz gut vorran, doch ich komme jetzt langsam an einen Punkt, wo Code sich wiederholt und alles zu unübersichtlich wird. Da bin ich auf Entities gestoßen.

Eine Einleitung habe ich hier bekommen: entity_tutorial [Slick Wiki]

Daraus habe ich es so verstanden, dass es nur die Klasse Entity gibt, die eine Liste von Komponenten hält, die jeweils alle spezielle Verhalten beschreiben, wie dort zum Beispiel die Bewegung. Das heißt im Endeffekt, dass ich dann am Ende mit einem riesigen Konstruktor darstehe für zum Beispiel einen Gegner, der z.B. laufen, springen, schießen kann und eventuell noch fröhlich mit Bananen um sich wirft... nur so als Beispiel 

Für mich als Gegensatz hab ich noch dieses gefunden: Coke and Code

Da sieht das für mich widerrum so aus, als liefe das wieder auf das Klassensystem heraus, dass ich im Moment schon habe, dass heißt ich hab eine Basisklasse, leite davon alles ab und hab am Ende wieder viel Code 2 mal getippt.

Oder sind das beides zwei unterschiedliche Sachen mit dem selben Namen ?


----------



## Fu3L (29. Sep 2012)

Diese Lektüre hat mir da selbst sehr geholfen:
T=Machine  Entity Systems are the future of MMOG development – Part 1

Du brauchst im Prinzip nicht mal eine Klasse Entity. Sondern nur eine Map<Integer, Map<Class<? extends Component>, Component>> der du alle Komponenten hinzufügst. Dann gibt es die EntitySysteme, die zum Beispiel jedem Entity mit der Component "Moveable" um seinen in dieser Component gespeicherten Geschwindigkeitswert verschiebt, wenn denn eine Anweisung zur Bewegung vorliegt. (Zum Beispiel durch den Nutzer oder die KI).
Lies am besten den Artikel, der sich zwar sehr auf MMOGs bezieht, aber auch in jedem anderen Spiel so genutzt werden kann.

Dieser Artikel erklärt es auch noch einmal deutlich, etwas kürzer und auch bezogen auf ein Singleplayer game: Cowboy Programming » Evolve Your Hierarchy (Der Autor hat an den Tony Hawk Spielen mitgearbeitet)


----------



## Lukas1995 (29. Sep 2012)

Wow, das ist eine ganze Menge.

Das scheint dann doch ein relativ komplexes Thema zu sein, ich werd mal sehen ob mir das liegt 

Danke an dich Fu3l, das hat mir dann doch sehr weitergeholfen


----------



## Lukas1995 (29. Sep 2012)

Ach, eine Frage hat sich dann doch noch aufgeworfen:

Nach dem Artikel Cowboy Programming » Evolve Your Hierarchy habe ich mich gefragt, ob die Klassen in dem "Komponentendiagramm" (Figure 2) so eine Art Container für Komponenten sind oder einfach nur... Beschreibungen für bestimmte Komponenten in dem Fall sind.

Das mit dem Container meine ich so:

Es gibt z.B. die Klasse Alien. Die Klasse Alien hat eine update- und render -Methode, sowie die Komponenten oder Objekte Position, Movement, Render etc, die dann bei jedem aufruf ihre Methoden machen.

Beschreibungen: 

man erstellt für Alien ein Entity-Objekt und gibt diesem dann die Komponenten dazu. -> endet leider in einem großen Konstruktor und evtl viele Überprüfungen auf Null-Referenzen.

Oder ist das ganz anders gemeint ?


----------



## Fu3L (29. Sep 2012)

Das ist das schwierige an einem EntitySystem, es hat (fast) nichts mehr mit OOP zu tun! Das ist schwierig und ich bin mir desssen bewusst, weil ich vor einigen Monaten selbst erst gelernt habe, was das bedeutet.

Es gibt keine Klasse Alien. Es gibt keine Klasse Enemy. Es gibt keine Klasse Player.
Jedes Entity wird zu dem was es ist, durch die Gesamtheit seiner Komponenten. Ein Beispiel: Wenn ich in einem MMORPG eine schwere Rüstung anlege, identifieziert man mich als Tank, wenn ich mir einen Zauberstab und entsprechende Skills zulege, werde ich als Magier identifiziert, auch ohne, dass ich irgendwo diese Rolle konkret gewählt hätte.

Jedes Entity ist erstmal eine Nummer und dieser Nummer werden die Komponenten zugewiesen. Am besten in einer Art Factory Methode. Also sowas wie createTank() und in dieser werden dann Componenten wie Moveable, Armored, und, und, und hinzugefügt. Kein Bedarf für NP Checks  
Im nächsten Schritt könnte man dadurch sogar weitergehen und die Konstruktionsanweisungen für Einheiten leicht aus Datenbanken auslesen. Generell kann man so seeeehr leicht die Objekte speichern (was ja sehr betont wird in den Artikeln): Ich brauche keine Methode zum Speichern pro Einheit, sondern nur pro Komponente. Dadurch kann ich eine neue Einheit als einzigartige Zusammenstellung von Komponenten kreieren, ohne auch nur eine Methode für das Speichern, Laden und auch Rendern zu schreiben. 
Du brauchst keine eigene Rendermethode mehr. Das ist auch eher eine Vereinfachung aus Quaxlies Tutorial und eher unüblich in Engines. Du hast eine Komponente, die anzeigt, dass dein Entity eine Darstellung hat und wenns zB ein Bild oder ein 3D-Modell ist, dann sollte diese Komponente eine eindeutige Identifizierung dieser Darstellung erlauben.
Dann erstellt man ein neues EntitySystem "Renderer" und dieses lädt dann für jedes Entity die Darstellung. Wenn es sieht: Ohh, Entity 10, dann guckt es in einer Map nach und sieht, dass dafür BildXY hinterlegt ist und zeichnet dieses. Natürlich können zB bei Vergiftungserscheinungen noch Komponenten hinzugefügt werden, wie "Greenish" und dann wird das Bild beim Rendern vom Renderer grünlich eingefärbt.

Diese Art der Einheitenverwaltung ist erstmal sehr nützlich, falls man das Parallelisieren möchte, denn jedes System ist unabhängig von den anderen und erst nach einem Durchlauf werden Änderungen an den Komponenten in die Datenbank gespeichert und beim nächsten Durchlauf wieder ausgelesen. Das können wir uns, wenn wir in einem Prozess und vllt auch in einem Thread arbeiten, sparen. Dadurch können wir Annahmen machen und uns zB merken, welche Entities neu in den Kreis der Entities mit zB einer Darstellung aufgenommen wurden. So muss der Renderer nicht jedes Mal alle Entities darauf untersuchen. (Wenn du mit einer Engine, die einen SceneGraph bereit hält, arbeitest, sollte der Renderer sowieso nur dafür verantwortlich sein, die Darstellungen an diesen an- und abzuhängen und dann auch anders heißen, weil dann ein anderer Teil der Engine fürs Zeichnen zuständig ist.)

Ich werde mal mein EntitiySystem etwas kommentieren und sehen, ob ichs mal hochladen kann


----------



## Lukas1995 (29. Sep 2012)

Klingt nach einiger Arbeit in der Umgewöhnung, nachdem mir beigebracht wurde, so objektorientiert zu denken 

Das wär klasse, wenn du das mal hochladen könntest, würde ich mir dann auf jeden Fall mal anschauen!
Danke dass du dir Zeit nimmst, mir zu helfen


----------



## Fu3L (8. Okt 2012)

Nachdem ich wenig Zeit hatte, möchte ich meine Ankündigung wahr machen und das EntitySysem hochladen. Ich hab nicht mehr wirklich aufgeräumt. Ich hoffe dennoch, dass man daraus Rückschlüsse für sein eigenes EntitySystem ziehen kann. 
In der obersten Ebene des Ordners liegt "ModelSystem.java", die beispielhaft den möglichen Aufbau eines Systems zeigt (habe ich einfach unverändert aus meinem Spiel kopiert). Des Weiteren habe ich den "ClientSynchronizer" dringelassen, den ich in meinem Spiel verwende, der müsste aber für eine allgemeine Verwendung einiges verändert werden. Es mag auch sein, dass er ineffizient arbeitet, das hab ich relativ schnell geschrieben 
Wenn noch weiteres Interesse an dem Thema beteht, könnte ich noch einen Thread aus dem JMonkey Forum suchen, in dem darüber diskutiert wurde.
PS: Einen Hinweis noch, den ich in meinem langen Text vergaß: Components sind Immutable, das heißt, sie werden nie verändert! Wenn man einem Entity eine andere Darstellung geben will, muss man die Komponente austauschen. Außerdem trägt die Komponente höchstens Informationen wie: "Model xY". Das Modell an sich, muss vom Renderer geladen werden, weil Komponenten so wie sie sind speicherbar sein müssen und wir wollen ja nicht immer das Modell mit abspeichern, sondern nur die Information welches Modell das entsprechende Entity nutzt.


----------

