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

moritz31

Treue Seele

  • »moritz31« ist der Autor dieses Themas

Beiträge: 259

Wohnort: Hessen

Beruf: Student

  • Private Nachricht senden

1

17.03.2013, 17:06

Sfml und Tilemap Kollision

Hey,
ich arbeite gerade an einer etwas größeren Tilemap. Das ganze klappt jetzt auch schon ganz gut, nur weiß ich nicht recht wie ich das mit den Kollisionen hinbekommen soll.
Ich hab um den Player ein sf::FloatRect, das jedes Frame aktualisiert wird. Jetzt hatte ich mir überlegt, dass ich alle Kollisionsobjekte aus dem Vector wo die Tilemap drin is nochmals in ein extra Vector kopiere,
und das ganze überprüfe. Jedoch stell ich mir das ganze sehr aufwendig für den PC vor. Am einfachsten wäre es doch eigentlich, wenn jedes Tile auf dem Bildschirm ein Rect hat, jedoch benutze ich ja nur ein Sprite :O

Kann mir jemand vllt weiterhelfen?

lg
Moritz

Nimelrian

Alter Hase

Beiträge: 1 216

Beruf: Softwareentwickler (aktuell Web/Node); Freiberuflicher Google Proxy

  • Private Nachricht senden

2

17.03.2013, 22:25

Punkt 1: Benutze für Tilemaps keine Sprites. NIE. Nimm lieber ein VertexArray, ist wesentlich ressourcenschonender und man erreicht das gleiche ;)

Punkt 2: Ich meinerseits benutze in der Tat einen vector mit Rects, die ich nach jeder Bewegung mit dem Playerrect vergleiche, und bei Bedarf eingreife. Hat sich nicht wirklich auf die Performance ausgewirkt. Falls du eine sehr große Map hast, solltest du die Rects eines Bereiches vllt. in Chunks zusammenfassen, und das Playerrrect nur mit den Rects in dem Chunk vergleichen, in dem er sich auch befindet.
Ich bin kein UserSideGoogleProxy. Und nein, dieses Forum ist kein UserSideGoogleProxyAbstractFactorySingleton.

moritz31

Treue Seele

  • »moritz31« ist der Autor dieses Themas

Beiträge: 259

Wohnort: Hessen

Beruf: Student

  • Private Nachricht senden

3

17.03.2013, 22:54

okay das mit den VertexArrays guck ich mir mal an :)

und zur tilemap also ich versucch das jetzt so, das ich einfach immer um den spieler herum die felder überprüfe und festegelegt hab in nem vector was für zeichen stehen für solid objekte

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

4

18.03.2013, 10:23

Punkt 2: Ich meinerseits benutze in der Tat einen vector mit Rects, die ich nach jeder Bewegung mit dem Playerrect vergleiche, und bei Bedarf eingreife. Hat sich nicht wirklich auf die Performance ausgewirkt. Falls du eine sehr große Map hast, solltest du die Rects eines Bereiches vllt. in Chunks zusammenfassen, und das Playerrrect nur mit den Rects in dem Chunk vergleichen, in dem er sich auch befindet.

In meinem Action Adventure habe ich keine Unterteilung in Chunks und dennoch ist die Kollisionsprüfung in Bezug auf die benötigte Rechenzeit mit der Umgebung vollkommen unabhängig von der Größe der Umgebung. Ich suche mir Anhand der Koordinaten des Spielers einfach die Felder heraus, mit denen er möglicherweise kollidieren könnte und prüfe nur mit diesen, ob es Kollisionen gibt.


und zur tilemap also ich versucch das jetzt so, das ich einfach immer um den spieler herum die felder überprüfe und festegelegt hab in nem vector was für zeichen stehen für solid objekte

Und du möchstest nun wissen, ob der Ansatz so gut ist? (Ich sehe jedenfalls keine Frage)
klingt nach einem verwendbaren Ansatz, nur denke ich, dass einzelne Zeichen für einzelne Felder (auf Dauer) nicht unbedingt so toll sind. Man schränkt sich ziemlich stark in der Anzahl der möglichen Felder ein und noch bevor man die maximale Anzahl an möglichen Feldern ausnutzen muss, wird man wohl Probleme mit der Unterscheidung der verschiedenen Zeichen haben. (Welches Zeichen ist welches Feld?)
Wenn du eine gute Editierbarkeit mittels Texteditor haben willst, dann solltest du eher richtige Namen verwenden (z. B. "grass", "water", "roof", ...) und ansonsten Zahlen, welche auch dem Index im Tileset entsprechen.


Aber mal ein paar weiter gehende Fragen: hast du nur eine einzige Ebene oder mehrere? Da du anhand der Art des Tiles auf Kollisionen prüfst, gehe ich von einer einzigen aus.
Was ist nun, wenn du ein solides Objekt auf einem begehbaren Untergrund platzieren willst? würdest du den Untergrund als Teil des Objekts behandeln und die Grafik des Untergrunds in die Grafik des Objekts übernehmen?
Wenn nun das Objekt verschwinden soll, müsstest du das Feld so anpassen, dass statt des Objekts mit dem Untergrund der richtige Untergrund angezeigt wird.

Wenn du mehrere Ebenen haben würdest, dann könntest du den Spieler auf eine dieser Ebenen setzen, beispielsweise auf die 2. Ebene (wenn die 1. den Boden darstellt).
Dann könntest du über das Vorhandensein von Feldern, also wenn einem Feld auch ein Tile des Tilesets zugewiesen wurde, die Kollisionsprüfung abhandeln und müsstest nicht separat definieren, womit man kollidiert.
Weiterhin kann man jedes beliebige Objekt auf jeden beliebigen Untergrund stellen, ohne dass für jede mögliche Kombination neue Grafiken angelegt werden müssen.
Du könntest fliegende Objekte haben, die die Kollision mit Objekten auf dem Boden nicht interessieren oder du könntest sehr einfach Brücken oder ähnliches basteln, von denen man einerseits verdeckt (darunter stehen) wird oder die man selbst verdeckt (darauf stehen).


Ich hoffe mal, du siehts meine Anmerkungen nicht zu kritisch. Das, was du dir bisher überlegt hast ist schon eine gute Grundlage und das, was ich hier genannt habe sind im Grunde nur Erweiterungen der Gedanken, die du bereits hattest. Es kann ja auch sein, dass du das von mir genannte für dein Spiel gar nicht benötigen wirst, aber dies einzuschätzen bleibt dir überlassen. ;)
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

moritz31

Treue Seele

  • »moritz31« ist der Autor dieses Themas

Beiträge: 259

Wohnort: Hessen

Beruf: Student

  • Private Nachricht senden

5

18.03.2013, 17:08

nein keinesfalls finde ich die anmerkung zu kritisch :) ich freue mich über jede kritik :)

ich hab mir das so gedacht, ich habe sozusagen spezielle durchsichtige Untergrundtiles, die Eigenschaften besitzen wie z.B. solid.
Dann setze ich einfach das Objekt z.B. ein Haus drüber :)

denke so ist das ganz gut machbar :)

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

6

18.03.2013, 19:48

Mal was anderes. Der Vorteil einer Tilemap ist doch unter anderem der, dass ich eine sehr schnelle/einfache Kollisionsroutine schreiben kann. Ich kann mir doch die Tileindizes der Tiles berechnen, welche vom Spieler verdeckt werden. Dann brauch ich nur noch diese Tiles zu checken. Warum sollte man denn da überhaupt auf die Idee kommen mit jedem Tile der Karte auf Kollision zu testen? Da würde ich doch einen riesen Vorteil er Rasterung verschenken. Mir würde jedenfalls einfallen, warum ich das so lösen sollte.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

moritz31

Treue Seele

  • »moritz31« ist der Autor dieses Themas

Beiträge: 259

Wohnort: Hessen

Beruf: Student

  • Private Nachricht senden

7

18.03.2013, 22:55

hat jemand vllt ne gute erklärung zu den VertexArrays weil ich steig da jetzt nicht so ganz durch :) aber finde die idee her sehr gut , vorallem da die map später mal richtig groß werden wird


lg moritz

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

8

19.03.2013, 11:49

Brauchst du alles nicht. Geh doch mal folgendermaßen vor. Du erstellst eine Klasse Tile. Diese stellt ein einzelnes Tile/Feld deiner Tilemap dar. Jetzt überlegst du dir was ein Tile so wissen muss. Machen wir es mal ganz einfach. Ein Tile hat eine Grafik und weiß ob es Begehbar ist oder nicht. Du könntest deiner Klasse nun also eine Textur und einen bool Wert für die beiden Informationen verpassen. Das ist grundlegend eigentlich schon ausreichend für ein einzelnes Tile. Je nachdem was du so vor hast kannst du diese Klasse dann erweitern.
Jetzt geht es um die Kollision. Wenn der Spieler maximal so groß wie ein Tile ist und sich nur direkt auf dem Raster bewegen kann, so musst du nur das Tile direkt unter dem Spieler überprüfen. Je nach Umsetzung der Bewegung wäre es natürlich das Tile vor dem Spieler. Nun diesen einfachen Fall hat man aber normal nicht. Normal bewegt sich der Spieler nicht nur Tile für Tile, sondern soll sich frei auf der ganzen Karte bewegen können. Also kann nicht einfach nur ein einzelnes Tile auf Kollision überprüft werden. Was weißt du denn über den Spieler?
Du kennst sein BoundingRect (Das Rechteck, welches Die Grafik des Spielers einschließt). Damit kann man ja schon ne Menge anfangen. Das BoundingRect gibt dir 4 wichtige Punkte auf der Karte:
Den Punkt oben Links vom Rechteck,
Den Punkt oben Rechts vom Rechteck,
Den Punkt unten Links vom Rechteck,
Den Punkt unten Rechts vom Rechteck,

Du musst also schon mal die Tiles überprüfen, welche genau unter diesen Punkten liegen. Wenn dein Spieler nun aber größer als ein einzelnes Tile sein kann, so kann es sein dass er mehr als nur 4 Tiles bedeckt. Die Lösung hierbei ist aber auch nicht besonders schwer. Um die jeweiligen Tiles unter den 4 Eckpunkten auf Kollision zu prüfen, musst du ja zuerst die Indizes der Tiles berechnen. Bei einem Spieler welcher größer als ein Tile ist könnten die so aussehen:
Oben Links: X=3, Y=5
Oben Rechts: X=5, Y=5
Unten Links: X=3, Y= 6
Unten Rechts: X=5, Y=6
Nun was fällt dir hier auf. Bei den Indizes für die X-Werte ist ein Sprung von 3 nach 5. Dazwischen liegt aber noch die 4. Dein Spieler bedeckt also auch das Feld mit der 4. Bei den Y-Werten ist kein Sprung, da auf 5 direkt die 6 folgt. Hier wird also kein weiteres Feld bedeckt. Überprüfen musst du also 6 Tiles in diesem Fall.
Ich schreib sie hier mal hin nach dem Schema Tile(X-Index, Y-Index):
Tile(3,5)
Tile(4,5)
Tile(5,5)
Tile(3,6)
Tile(4,6)
Tile(5,6)

So könnte das ganze im Prinzip aussehen. Du musst also nur noch von den Koordinaten des Spieler den Index der darunter liegenden Tiles berechnen. Wenn du da nicht allein drauf kommst, dann such bei Google einfach mal nach Tutorials zu Tile-Maps. Das sollte eigentlich in jedem Tutorial dran kommen. Niemand würde eine Tile-Map benutzen und dann auf Kollision mit jeden Feld überprüfen.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

moritz31

Treue Seele

  • »moritz31« ist der Autor dieses Themas

Beiträge: 259

Wohnort: Hessen

Beruf: Student

  • Private Nachricht senden

9

21.03.2013, 23:31

okay danke :) funktioniert jetzt alles prima :)
hab es jetzt ähnlich gemacht wie schorsch es beschrieben hat

Werbeanzeige