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

1

12.03.2015, 16:36

Integration einer TileMap mit Artemis

Hallo zusammen!

Seit einiger Zeit arbeite ich versuchsweise mit Artemis (einem Entity System Framework (ESF)).
Ich verwende dabei folgenden C++ Port (Link).

Die grundsätzliche Idee eines solchen ESF birgt meiner Meinung nach einige Vorteile.
Komponenten beinhalten nur Daten, die Systeme kombinieren gewünschte Komponenten und machen die Logic aus.
Den einzelnen Spielobjekten werden entsprechend Komponenten beigefügt. Das ganze ist extrem flexibel und nach einiger
Zeit auch recht überschaubar.

Ich habe mittlerweile hinbekommen, dass Objekte in einem gewünschten Level über den MapEditor Tiled geladen werden.
Die Frage stellt sich mir nun, wie behandle ich meine TileMap?

Ein erster Versuch scheint wie folgt zu funktionieren, doch ich habe grosse Bedenken wenn es um die Performance geht:
Ich habe wie auch die Objekte jedes einzelne TileMap als Spielobjekt behandelt und entsprechend Komponenten zugeteilt.
Genau gesagt: TileComponent, PositionComponent, TransformComponent und CollisionComponent. Die einzelnen Tiles werden
eben wie gesagt als Spielobjekte behandelt und erhalten einen einzigartigen Tag welcher sie im GroupManager zu einer Einheit
fasst. Wenn es nun um Kollision mit den TileMap geht kann ich einfach alle Objekte welche mit dem entsprechenden Tag behaftet
sind in einen vector verwerfen und diesen dann z.B. mit meinem Spielobjekt für eine Kollision abfragen.
Dies scheint nun zwar zu funktionieren, aber habe ich eine grössere Map mit vielen einzelnen Tiles so geht die CPU Leistung rasch
auf 100% auch wenn das Spiel noch nicht stark zu laggen scheint.

Hat jmd. anderes auch schon mit Artemis bzw. einem anderen ESF gearbeitet und sich dieser Frage gestellt?
Was für andere Lösungsansätze wären denkbar?

Danke schon im voraus für eure Antworten.

Eric

DeKugelschieber

Community-Fossil

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

2

12.03.2015, 17:40

Das Problem liegt ja nicht in deinem "ESF" System, sondern daran dass alle Tiles für die Kollision genutzt werden. Was nicht nötig ist.
Hier ist ein anderes Design sinnvoll. Du könntest z.B. immer die aktuellen 8 Felder um den Spieler bestimmen und nur diese zur Kollisionserkennung nutzen. Wenn sich der Spieler bewegt werden die Tiles neu ausgewählt.

Noch was anderes: wenn du jedes Tile einzeln renderst hast du schnell so viele Draw Calls, das die Performance drastisch in den Keller geht. Auch hier macht es Sinn einen anderen Ansatz zu wählen. Z.B. mehrere oder gar alle (hängt von der größe der Karte ab) Tiles zu batchen und zusammen zu rendern. Die Logik für Kollision usw. musst du nicht ändern, da diese ja nicht sichtbar ist.
Für meine WebGL Engine hatte ich mal eine Tilemap programmiert die die Map in einen großen Buffer batchen kann, damit war es möglich bis zu 400.000 Tiles ohne merkbaren verlust zu rendern. Mehr wäre dann möglich wenn man eben nicht einen großen Buffer nimmt, sondern mehrere und dadurch maximal 4 (an den Ecken) Draw Calls zu mittel großen Buffern hat.

Es wäre übrigens noch gut zu wissen welche anderen Frameworks/Technologien du verwendest. Das System dass du nutzt ist grundsätzlich nicht schuld.

DeKugelschieber

Community-Fossil

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

3

12.03.2015, 20:11

Betrachte die TileMap als einzellnde Komponente. Nicht jedes Tile verfügt über eine CollisionComponent, sondern deine TileMap nur. Die Tiles kannst du ja trotzdem flaggen, welches Tile eine Collision hat und welches nicht. Kannst ja eine TileMapCollisionComponent machen.

Ich würde eine TileMap eher als Objekte betrachten. Die Tiles selber nicht.

?

4

12.03.2015, 22:19

Danke für eure Antworten.
Ich arbeite mit der SDL 2.0.3, für die Physik verwende ich meine eigene Engine.

@DeKugelschieber:
Das Konzept der Kollisionserkennung in Bezug auf die aktuelle Spielerposition leuchtet mir ein. Ich muss mir noch einige Gedanken hierzu machen, wie ich dies am
Besten umzusetzen habe.

Mir ist aktuell jedoch noch nicht ganz klar, wie ich z.B. meine komplette TileMap rendern soll (sprich z.B. 1x Draw Call). Aktuell wird ja wie gesagt jedes einzelne Tile mit
einem Draw-Call gerendert, in etwa so:

C-/C++-Quelltext

1
g_pTextureManager->drawTile(ID, position, spacing, xKoordinate, yKoordinate, height, width ..... );


Wie kann ich mehrere Tiles batchen und dann gemeinsam rendern?

@Bambi:
Verstehe ich dies richtig? Ich könnte ein Entity erstellen und dieser Entity eine TileMapKomponente geben, welche die Tiled-Map übergeben würde. In einem TileMapSystem würde ich
bei der Initialisierung eine map erstellen wo klar wird wo welche Art von Tile zu liegen kommt. In einer separaten Render, welche ständig geloopt wird würde ich die Draw-Calls machen.

Wie soll dann die Kollision genau funktionieren?

DeKugelschieber

Community-Fossil

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

5

13.03.2015, 09:01

Hmm was es da jetzt direkt gibt um mit SDL zu batchen weiß ich nicht. In OpenGL hätte ich einfach ein VBO (bzw. mehrere für Texturkoordinaten usw.) genommen. Problem daran ist natürlich dass die Karte statisch wird, da du erstmal nicht direkt ein Tile visuell verändern kannst. Das geht nur wenn du den ganzen Buffer updatest. Hier kann man evt. statisches Gelände und bewegliche Tiles oder Tiles mit Interaktionsmöglichkeiten von den statischen trennen.

Das was Bambi geschrieben hat verstehe ich nicht. Aber evt. geht es ihm darum dass Logik und Darstellung getrennt werden können?
Du kannst deine Kollisionserkennung auch erstmal beibehalten und zumindest die Darstellung verbessern und gucken ob es dann läuft.
Mit dem "ein Tile ein Draw Call" Ansatz wirst du schnell an deine Grenzen stoßen.

Ich habe hier noch JS Code der eine Tilemap batch (Methode batch), vielleicht hilft dir das. Soweit ich weiß kann man mit SDL auch ganz gut direkt OpenGL nutzen.

Werbeanzeige