Entität / Komponentensystem und Benutzeroberfläche "Entitäten"

14

Ich bin immer noch grün zu Entity / Component-Systemen. Ich finde, da ich nützliche Komponenten zum Zeichnen von Sprites (oder Spritesheets) und zum Handhaben von Eingaben (Maus- / Touch-Klicks) habe, möchte ich diese natürlich wiederverwenden, um UI-Komponenten (wie Schaltflächen, z. B. Ebenenauswahlbildschirm) zu erstellen.

Das kommt mir sehr merkwürdig vor. Ich verstand Entitäten immer als "Spielmodell" wie Spieler, Feinde, Power-Ups usw. Andererseits ist es aus Sicht der Wiederverwendung von Code durchaus sinnvoll, Komponenten für die Benutzeroberfläche wiederzuverwenden.

Wie (und wo) passen UI / GUI-Bedenken in ein Entitäts- / Komponentensystem?

(Hinweis: Diese Frage ist plattformunabhängig, da sie für mehrere Plattformen / Sprachen gilt.)

ashes999
quelle
3
Ich denke, es scheint nur logisch für Sie, weil Sie 2d Spiel machen. Stellen Sie sich vor, Sie erstellen ein 3D-Spiel (mit 2D-GUI), bei dem fast keine Renderlogik wiederverwendet werden kann und 2D-GUI-Komponenten in der 3D-Welt keinen großen Sinn ergeben. Sie sollten die GUI auf dem Komponentensystem erstellen. Lass deinen GameplayScreen eine Entity-Welt mit Komponenten erstellen, und eine der Komponenten ist eine Kamera mit "Canvas", auf die dein Renderer zeichnet. Und diese Leinwand wird zum Hintergrund dieses Bildschirms.
Kikaimaru
1
@Kikaimaru Sie haben einen Punkt über 2D. Vielleicht mag ich MVC zu sehr, aber es scheint eine Mischung aus "Modell" (Spieleinheiten) und Ansicht / Controller (UI-Komponenten) zu sein. Es funktioniert zwar, aber sollte es auch so funktionieren? Gibt es bessere Wege? Wie machen es andere?
ashes999
@ Ashes999 Ihr Kommentar und erste Frage ist aus tiefstem Herzen :)
Narek
@Armen Darauf habe ich nie eine zufriedenstellende Antwort bekommen.
Asche999
@ashes999 mich an. Überall wird gesagt, dass Sie MVC nicht mit ECS mischen sollten, aber warum? Wäre es nicht schön? Unterschiedliche Waffe für unterschiedliche Aufgaben, stimmst du nicht zu?
Narek

Antworten:

4

Nachdem ich mehrere Entity-Component-Systeme, insbesondere CraftyJS, verwendet hatte, erhielt ich mehr oder weniger die Antwort auf meine Frage: Ja, Sie können Komponenten (insbesondere Sprites oder Bilder und Mausklick-Handler in 2D-Spielen) für die GUI wiederverwenden.

In den meisten Fällen haben Sie nur Zugriff auf das ECS und nicht auf die zugrunde liegenden Systeme (z. B. Zeichensystem). In diesem Fall ist es in Ordnung, Komponenten zu verwenden, da Sie keine andere Wahl haben.

Wenn Sie Zugriff auf das zugrunde liegende System haben (z. B. Ruby Roguelike mit direktem Zugriff auf Curses), ist das Zeichnen / Rendern direkt auf diesem System möglicherweise effektiver (weniger Code, weniger zerbrechlich, natürlicher) als die Verwendung einer Reihe von Entitäten und Komponenten.

ashes999
quelle
Woher nimmst du die Logik fortgeschrittener UI-Elemente? Dh Ein Gesundheitsriegel, der wissen muss, wann der Spieler getroffen wird und wie viel er senken muss. Ich kann nicht erkennen, ob es ein bestimmtes System oder ein Skript oder etwas anderes braucht ...
Emir Lima
@EmirLima für so etwas würde ich den größten Teil der UI-Logik in die Health-Leiste einfügen (die Größe der Health-Leiste ändern) und den Spieler veranlassen, ein Ereignis zu generieren, wenn er getroffen wird, das angibt, wie hoch der neue / geänderte Health-Wert ist. (Die Gesundheitsleiste kann dieses Ereignis erfassen und entsprechend reagieren.)
ashes999
Aber was ist das Health-Bar-Objekt in dieser Architektur? Ist es eine Entität mit einer "Health Bar" -Komponente? Eine Klasse, die von Entity erbt? Ein normales Objekt mit Update-Aufrufen fest codiert?
Emir Lima
1
@EmirLima Ich würde die Gesundheitsleiste als Entität und den Spieler als Entität modellieren. Sie können alles tun, was für Sie sinnvoll ist.
Asche999
1

In 2D oder 3D sollte ein Entity Component System (ECS) mindestens Zugriff auf das GUI-System haben, wenn es nicht Teil desselben ECS ist.

Persönlich würde ich die beiden nicht mischen. Die Wiederverwendbarkeit von Code für eine GUI geschieht wirklich nur auf oberster Ebene. Antworten auf Maus / Tastatur, Rendern usw. Die Funktionen der verschiedenen Schaltflächen oder die Informationen, die in bestimmten Listen angezeigt werden, können nicht generisch genug gestaltet werden, um sie wiederzuverwenden.

Zum Beispiel würde ich mir vorstellen, dass die Komponenten für GUI-Entitäten so ähnlich positionsind wie renderundgui . Wo die GUI-Komponente die Art der Aktion definieren würde, die die GUI-Entität ausführt. Diese Aktion wird jedoch ziemlich einzigartig und kontextspezifisch sein. Dies führt dazu, dass das System, das GUI-Komponenten verarbeitet, sehr groß ist und im Wesentlichen für die einzelnen GUI-Funktionen (Laden des Spiels, Speichern des Spiels, Suchen des Servers usw.) ausgelegt ist. Klingt unordentlich.

Ich würde es vorziehen, eine Standardklassendatei für jeden GUI "Bildschirm" zu erstellen. Haben Sie alle Funktionen für diesen Bildschirm an einem Ort (mit Verweisen auf eine gemeinsame Funktionsklasse). Es ist viel ordentlicher und einfacher zu handhaben.

Wie gesagt, das ECS sollte jedoch Zugriff auf das GUI-System haben. Es muss in der Lage sein, Informationen basierend auf Entitäten in seinen Systemen an die GUI zu liefern. Wenn Sie zum Beispiel über eine verbündete Einheit fahren, wird ein GUI-Fenster mit allen Informationen zu dieser Einheit geöffnet. Wenn Sie über einer feindlichen Einheit schweben, wird ein GUI-Fenster mit begrenzten Informationen geöffnet. Sie möchten die GUI wahrscheinlich nicht so programmieren, dass sie den Unterschied zwischen beiden erkennt. Sie möchten die Entität auffordern, ihre Informationen anzuzeigen.

Entitäten werden also wahrscheinlich immer noch eine Art GUI-Komponente haben, aber sie werden Entitäten "im Spiel" sein, keine GUI-Entitäten. Diese Komponente verwendet das externe GUI-System, um ihre GUI-Schnittstelle zu erstellen.

MichaelHouse
quelle
Klingt so, als ob das System, das ich habe, ganz anders ist als das, das Sie beschrieben haben. Ich habe Entitätsklassen wie TouchButtondie, die sich aus einem Spritesheet und einem Touch-Click-Listener zusammensetzen. Für das Unit-Popup würde ich das wahrscheinlich als Kombination aus Sprite-Komponente + Mouse-Listener-Komponente implementieren. Hmm.
Asche999