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

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

11

03.07.2014, 12:20

Im Prinzip wurde schon alles wichtige gesagt. Den allgemeinen Aufbau einer Tilemap kennst du ja denke ich. Ob du jetzt std::vector, std::array, ein normales Array, ein zweidimensionales Array oder was weiß ich benutzt spielt im Prinzip erst mal keine Rolle. Das ist ja nur die intere Datenhaltung deiner Map.
Wenn du eine zweidimensionale Struktur benutzt, dann kannst du direkt über 2 Indizes (x und y) auf die Tiles zugreifen und bei einer eindimensionalen Struktur würdest du dir eine Funktion schreiben die von den zwei Koordinaten x und y auf den Index umrechnet. Das sollte hoffentlich alles klar sein und du weißt hoffentlich wie du den Part umsetzen kannst. Wenn nicht, dann musst du dir das ganze noch mal angucken und gegebenenfalls nachfragen.
Festhalten können wir also dass du eine Datenstruktur hast um die Tiles zu speichern die deine Map bilden und dass du über die Koordinaten x und y darauf zugreifen kannst.
Ich würde jetzt so vorgehen und sagen, wenn der Benutzer eine neue Map erstellt so öffnet sich ein Dialog in welchem er die Größe der Map festlegen kann. Hier können von mir aus zusätzliche Dinge angegeben werden wie Name der Map, Tilegröße, Tileset und was du sonst so alles benötigst. Mach dir hier einfach Gedanken was der Benutzer bestimmen kann und was vorab klar für dein Programm sein sollte. Für den Anfang reicht es ja wenn du hier nur die Größe angeben kannst und der Rest fest vom Programm vorgegeben ist. Erweitern kannst du später immer noch. Jetzt wirst du irgendein Fenster haben in welchem die Karte selbst erstellt wird. Wie du ja selbst weißt benutzen die meisten Tilemapeditoren ein Raster (welches normal auch als solches zu erkennen ist) auf welchem du die Tiles dann verteilst. Du kennst die Größe der Map und die Größe eines Tiles und kannst du das Raster zeichnen. Entweder renderst du einfache Linien und baust dir damit ein Raster, oder hast eine Große Grafik für das ganze Raster (dann musst du für passende Grafikgrößen sorgen da die Maps verschieden groß sein können sollen). Um das zu umgehen kannst du auch einfach eine Grafik in der Größe eines einzelnen Tiles machen. Diese Grafik ist eine Zelle deines Rasters. Jetzt renderst du im Prinzip dieses Rastertile über die ganze Map. Im Prinzip splittest du so die Grafik deines großen Rasters auf eine kleine Grafik die du dann im Programm nebeneinander setzt. Selbes Prinzip wie bei Tilemaps auch. Du stückelst eine Große Grafik und setzt sie im Programm passend zusammen.
Wenn dein Benutzer mit der Maus über die Map fährt, so kannst du jetzt auch einzelne Tiles highlighten damit der Benutzer direkt erkennt welche Fläche er bearbeitet. Wenn der Benutzer jetzt zum Beispiel ein Tile setzen möchte wird er ja vermutlich einfach auf die Map klicken müssen. Dein Programm muss also verstehen welche Zelle deiner Map unter der Maus liegt. Ich erkläre das ganze mal für einen Editor ohne Scrollbars. Willst du Scrollbars oder einen anderen Scrollmechanismus einbauen um größere Maps zu erstellen muss das ganze ein wenig angepasst werden. Das überlasse ich erst mal dir, ich will dir ja nicht die ganze Arbeit abnehmen.
Du kennst normalerweise die Koordinaten der Maus und du willst die Indizes X und Y der darunterliegenden Kachel wissen. Du weißt wie hoch und wie breit eine Kachel ist. Ich vereinfache das ganze mal ein wenig und lege ein paar Dinge fest.
Deine Map besitzt kein scrolling und wird oben links in die Ecke (an Koordinate 0,0) gerendert. Das heißt das Tile mit der Position 0,0 wird in deinem Fenster auch an die Position 0,0 gerendert. Das Tile mit der Position 1,0 würde dann zum Beispiel rechts neben das erste gerendert. Im Prinzip wie bei jeder anderen Map auch. Mir geht es nur darum dass wenn du einen Offset für deine Map einbaust (zum Beispiel für irgendwelche Menüs) dann muss dieser natürlich auch in deinen Berechnungen bedacht werden. Bevor das hier zu kompliziert wird und ich dich nur verwirre, vergiss das vielleicht erst mal einfach und mach dir da keine Gedanken. Um also die Indizes für ein Tile unter der Maus zu berechnen tust du folgendes:
IndexX = MausX / TileBreite
IndexY = MausY / TileHöhe
und das ist schon alles. Wie gesagt man kann das ganze um einen Offset erweitern falls einige Dinge neben oder vor die Map gerendert werden sollen. Für eine scroll-Funktion der Karte wäre ein Offset auch zu bedenken. Das würde ich aber erst mal alles weg lassen. Fang erst mal ganz einfach an.
Nachträglich kannst du über eine Funktion nachdenken um die Größe der Map nachträglich verändern zu können. Da würde ich mich aber drum kümmern wenn der Rest klappt. Sonst musst du über zu viel auf einmal nachdenken und kommst am Ende nur durcheinander. Sinnvoll ist es sicherlich wenn du dir mal andere Tileeditoren anguckst. Tiled ist da ein gutes Beispiel für einen sehr guten Editor der sehr viel kann. Bei Youtube gibt es sicherlich einige Videos in welchen Leute ihre eigenen Editoren vorstellen. Da könntest du auch mal drüber gucken. Dann solltest du dir bewusst werden was dein Editor können soll und wie man damit arbeiten soll. Wie gesagt, mach nicht zu viel auf einmal. Fang lieber erst mal kleiner an und Baue neue Features lieber nacheinander ein.
„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.“

12

03.07.2014, 13:27

Im Prinzip wurde schon alles wichtige gesagt. Den allgemeinen Aufbau einer Tilemap kennst du ja denke ich. Ob du jetzt std::vector, std::array, ein normales Array, ein zweidimensionales Array oder was weiß ich benutzt spielt im Prinzip erst mal keine Rolle. Das ist ja nur die intere Datenhaltung deiner Map.
Wenn du eine zweidimensionale Struktur benutzt, dann kannst du direkt über 2 Indizes (x und y) auf die Tiles zugreifen und bei einer eindimensionalen Struktur würdest du dir eine Funktion schreiben die von den zwei Koordinaten x und y auf den Index umrechnet. Das sollte hoffentlich alles klar sein und du weißt hoffentlich wie du den Part umsetzen kannst. Wenn nicht, dann musst du dir das ganze noch mal angucken und gegebenenfalls nachfragen.
Festhalten können wir also dass du eine Datenstruktur hast um die Tiles zu speichern die deine Map bilden und dass du über die Koordinaten x und y darauf zugreifen kannst.
Ich würde jetzt so vorgehen und sagen, wenn der Benutzer eine neue Map erstellt so öffnet sich ein Dialog in welchem er die Größe der Map festlegen kann. Hier können von mir aus zusätzliche Dinge angegeben werden wie Name der Map, Tilegröße, Tileset und was du sonst so alles benötigst. Mach dir hier einfach Gedanken was der Benutzer bestimmen kann und was vorab klar für dein Programm sein sollte. Für den Anfang reicht es ja wenn du hier nur die Größe angeben kannst und der Rest fest vom Programm vorgegeben ist. Erweitern kannst du später immer noch. Jetzt wirst du irgendein Fenster haben in welchem die Karte selbst erstellt wird. Wie du ja selbst weißt benutzen die meisten Tilemapeditoren ein Raster (welches normal auch als solches zu erkennen ist) auf welchem du die Tiles dann verteilst. Du kennst die Größe der Map und die Größe eines Tiles und kannst du das Raster zeichnen. Entweder renderst du einfache Linien und baust dir damit ein Raster, oder hast eine Große Grafik für das ganze Raster (dann musst du für passende Grafikgrößen sorgen da die Maps verschieden groß sein können sollen). Um das zu umgehen kannst du auch einfach eine Grafik in der Größe eines einzelnen Tiles machen. Diese Grafik ist eine Zelle deines Rasters. Jetzt renderst du im Prinzip dieses Rastertile über die ganze Map. Im Prinzip splittest du so die Grafik deines großen Rasters auf eine kleine Grafik die du dann im Programm nebeneinander setzt. Selbes Prinzip wie bei Tilemaps auch. Du stückelst eine Große Grafik und setzt sie im Programm passend zusammen.
Wenn dein Benutzer mit der Maus über die Map fährt, so kannst du jetzt auch einzelne Tiles highlighten damit der Benutzer direkt erkennt welche Fläche er bearbeitet. Wenn der Benutzer jetzt zum Beispiel ein Tile setzen möchte wird er ja vermutlich einfach auf die Map klicken müssen. Dein Programm muss also verstehen welche Zelle deiner Map unter der Maus liegt. Ich erkläre das ganze mal für einen Editor ohne Scrollbars. Willst du Scrollbars oder einen anderen Scrollmechanismus einbauen um größere Maps zu erstellen muss das ganze ein wenig angepasst werden. Das überlasse ich erst mal dir, ich will dir ja nicht die ganze Arbeit abnehmen.
Du kennst normalerweise die Koordinaten der Maus und du willst die Indizes X und Y der darunterliegenden Kachel wissen. Du weißt wie hoch und wie breit eine Kachel ist. Ich vereinfache das ganze mal ein wenig und lege ein paar Dinge fest.
Deine Map besitzt kein scrolling und wird oben links in die Ecke (an Koordinate 0,0) gerendert. Das heißt das Tile mit der Position 0,0 wird in deinem Fenster auch an die Position 0,0 gerendert. Das Tile mit der Position 1,0 würde dann zum Beispiel rechts neben das erste gerendert. Im Prinzip wie bei jeder anderen Map auch. Mir geht es nur darum dass wenn du einen Offset für deine Map einbaust (zum Beispiel für irgendwelche Menüs) dann muss dieser natürlich auch in deinen Berechnungen bedacht werden. Bevor das hier zu kompliziert wird und ich dich nur verwirre, vergiss das vielleicht erst mal einfach und mach dir da keine Gedanken. Um also die Indizes für ein Tile unter der Maus zu berechnen tust du folgendes:
IndexX = MausX / TileBreite
IndexY = MausY / TileHöhe
und das ist schon alles. Wie gesagt man kann das ganze um einen Offset erweitern falls einige Dinge neben oder vor die Map gerendert werden sollen. Für eine scroll-Funktion der Karte wäre ein Offset auch zu bedenken. Das würde ich aber erst mal alles weg lassen. Fang erst mal ganz einfach an.
Nachträglich kannst du über eine Funktion nachdenken um die Größe der Map nachträglich verändern zu können. Da würde ich mich aber drum kümmern wenn der Rest klappt. Sonst musst du über zu viel auf einmal nachdenken und kommst am Ende nur durcheinander. Sinnvoll ist es sicherlich wenn du dir mal andere Tileeditoren anguckst. Tiled ist da ein gutes Beispiel für einen sehr guten Editor der sehr viel kann. Bei Youtube gibt es sicherlich einige Videos in welchen Leute ihre eigenen Editoren vorstellen. Da könntest du auch mal drüber gucken. Dann solltest du dir bewusst werden was dein Editor können soll und wie man damit arbeiten soll. Wie gesagt, mach nicht zu viel auf einmal. Fang lieber erst mal kleiner an und Baue neue Features lieber nacheinander ein.
Wow, danke das wsr sehr informativ :thumbsup:

13

03.08.2014, 22:50

Soweit habe ich es geschafft einen kleinen Tilemap Editor zu programmieren. ^^
Doch ein kleines Problem gäbe es da noch. Wenn der Benutzer jetzt für die Größe der Tilemap X=300 und Y=400 eingibt und sagen wir mal für das einzelnde Tile dann X=30 und Y=40 dann würde
man ja ein Feld von 30*40 großen Tiles bekommen. Mein Problem ist halt nur wenn der Benutzer jetzt für das einzelnde Tile X=40 und Y= 30 eingibt ist das natürlich kein Feld mehr sondern ein Feld aus 11*9 und einem Rest
von eins. Also ist das Tile Feld jetzt 99 Tiles Groß mit einem kleinem Teil unten dran. Ich hoffe ihr konntet mir bis hierhin folgen.
Würde mich über eine Antwort freuen.

MFG
Sceiwen

14

03.08.2014, 23:00

Ich glaube du hast da einen Denkfehler: Die Welt-Größe ergibt sich aus der Anzahl der Tiles (die Zahl, die du abfrägst, in deinem Fall <300, 400>). Daneben hast du die Größe der einzelnen Tiles (<40, 30>). Die insgesamte Fläche in Pixeln beträgt dann Weltgröße * Tile-Größe, in deinem Fall also <12000, 12000>. Du teilst nicht die Weltgröße durch die Tile-Größe, da die Weltgröße ja per Definition in Tiles angegeben wird. Um von Tiles nach Pixeln zu kommen musst du ja nur noch mit der Größe eines Tiles in Pixeln multiplizieren.

KeksX

Community-Fossil

Beiträge: 2 107

Beruf: Game Designer

  • Private Nachricht senden

15

03.08.2014, 23:03

Wie Schorsch schon gesagt hat, ist es vielleicht auch einfacher, wenn du erstmal ne feste Größe vorgibst und damit arbeitest.
WIP Website: kevinheese.de

16

04.08.2014, 13:25

Ich glaube du hast da einen Denkfehler: Die Welt-Größe ergibt sich aus der Anzahl der Tiles (die Zahl, die du abfrägst, in deinem Fall <300, 400>). Daneben hast du die Größe der einzelnen Tiles (<40, 30>). Die insgesamte Fläche in Pixeln beträgt dann Weltgröße * Tile-Größe, in deinem Fall also <12000, 12000>. Du teilst nicht die Weltgröße durch die Tile-Größe, da die Weltgröße ja per Definition in Tiles angegeben wird. Um von Tiles nach Pixeln zu kommen musst du ja nur noch mit der Größe eines Tiles in Pixeln multiplizieren.

Also soll der Benutzer die Breite und die Höhe des einzelden Tiles angeben können und dann noch wie viele er auf der X und Y Koordinate haben möchte ?
Denn ich kann mir schlecht vorstellen die komplette Größe nur aus der Breite und Höhe jedes einzelden Tiles zu berechenen.

KeksX

Community-Fossil

Beiträge: 2 107

Beruf: Game Designer

  • Private Nachricht senden

17

04.08.2014, 13:57

Ich glaube du hast da einen Denkfehler: Die Welt-Größe ergibt sich aus der Anzahl der Tiles (die Zahl, die du abfrägst, in deinem Fall <300, 400>). Daneben hast du die Größe der einzelnen Tiles (<40, 30>). Die insgesamte Fläche in Pixeln beträgt dann Weltgröße * Tile-Größe, in deinem Fall also <12000, 12000>. Du teilst nicht die Weltgröße durch die Tile-Größe, da die Weltgröße ja per Definition in Tiles angegeben wird. Um von Tiles nach Pixeln zu kommen musst du ja nur noch mit der Größe eines Tiles in Pixeln multiplizieren.

Also soll der Benutzer die Breite und die Höhe des einzelnen Tiles angeben können und dann noch wie viele er auf der X und Y Koordinate haben möchte ?
Denn ich kann mir schlecht vorstellen die komplette Größe nur aus der Breite und Höhe jedes einzelnen Tiles zu berechenen.


Wenn du 256 Tiles auf der X-Achse hast und 256 auf der Y-Achse, und jedes Tile ist 32*32px groß, dann kannst du für das Tile auf Position 256/256 folgendes machen:
TileX = (256-1) * 32;
TileY = (256-1) * 32;

Das -1 kommt daher, dass das erste Tile bei 0 ist.
WIP Website: kevinheese.de

18

04.08.2014, 15:24

Ich glaube du hast da einen Denkfehler: Die Welt-Größe ergibt sich aus der Anzahl der Tiles (die Zahl, die du abfrägst, in deinem Fall <300, 400>). Daneben hast du die Größe der einzelnen Tiles (<40, 30>). Die insgesamte Fläche in Pixeln beträgt dann Weltgröße * Tile-Größe, in deinem Fall also <12000, 12000>. Du teilst nicht die Weltgröße durch die Tile-Größe, da die Weltgröße ja per Definition in Tiles angegeben wird. Um von Tiles nach Pixeln zu kommen musst du ja nur noch mit der Größe eines Tiles in Pixeln multiplizieren.

Also soll der Benutzer die Breite und die Höhe des einzelnen Tiles angeben können und dann noch wie viele er auf der X und Y Koordinate haben möchte ?
Denn ich kann mir schlecht vorstellen die komplette Größe nur aus der Breite und Höhe jedes einzelnen Tiles zu berechenen.


Wenn du 256 Tiles auf der X-Achse hast und 256 auf der Y-Achse, und jedes Tile ist 32*32px groß, dann kannst du für das Tile auf Position 256/256 folgendes machen:
TileX = (256-1) * 32;
TileY = (256-1) * 32;

Das -1 kommt daher, dass das erste Tile bei 0 ist.
Danke, das habe ich bis dahin auch verstanden nur mich würde mal interessieren was der Benutzer jetzt geanu für Werte angeben muss damit dann diese Map ensteht.

KeksX

Community-Fossil

Beiträge: 2 107

Beruf: Game Designer

  • Private Nachricht senden

19

04.08.2014, 15:39

Ich glaube du hast da einen Denkfehler: Die Welt-Größe ergibt sich aus der Anzahl der Tiles (die Zahl, die du abfrägst, in deinem Fall <300, 400>). Daneben hast du die Größe der einzelnen Tiles (<40, 30>). Die insgesamte Fläche in Pixeln beträgt dann Weltgröße * Tile-Größe, in deinem Fall also <12000, 12000>. Du teilst nicht die Weltgröße durch die Tile-Größe, da die Weltgröße ja per Definition in Tiles angegeben wird. Um von Tiles nach Pixeln zu kommen musst du ja nur noch mit der Größe eines Tiles in Pixeln multiplizieren.

Also soll der Benutzer die Breite und die Höhe des einzelnen Tiles angeben können und dann noch wie viele er auf der X und Y Koordinate haben möchte ?
Denn ich kann mir schlecht vorstellen die komplette Größe nur aus der Breite und Höhe jedes einzelnen Tiles zu berechenen.


Wenn du 256 Tiles auf der X-Achse hast und 256 auf der Y-Achse, und jedes Tile ist 32*32px groß, dann kannst du für das Tile auf Position 256/256 folgendes machen:
TileX = (256-1) * 32;
TileY = (256-1) * 32;

Das -1 kommt daher, dass das erste Tile bei 0 ist.
Danke, das habe ich bis dahin auch verstanden nur mich würde mal interessieren was der Benutzer jetzt geanu für Werte angeben muss damit dann diese Map ensteht.



Die Größe der Map: Wie viele Tiles gibt es nach X und Y?
Die Größe eines Tiles: Wie viele Pixel gibt es nach X und Y?


Zweiteres solltest du eventuell erstmal fix lassen. 32 px breit, 32 px hoch zum Beispiel.
WIP Website: kevinheese.de

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

20

04.08.2014, 15:44

Eine Tilemap besteht aus einem Tileset (eine Sammlung grafischer Repräsentationen), bei den jedes Tile über eine bestimmte Pixelbreite und -höhe verfügt und sie besteht aus einer Sammlung von Zuweisung dieser zu Positionen auf der Map. Da eine Tilemap eine bestimmte Breite und Höhe in Tiles besitzt und jedes Tile auf einem Raster liegt, findet die erwähnte Zuweisung meist über ein 2-dimensionales Array (bzw. vergleichbare Strukturen der jeweiligen Sprache) statt.
Was der Benutzer beim Anlegen also angeben muss, ist definitv die Breite, die Höhe und das Tileset der Map. Wenn man sich an anderen vergleichbaren Tools orientiert (RPG Maker, Tiled, ...), dann sollte die Zuweisen, welches Tile an welcher Stelle verwendet werden soll, über ein "Bemalen" der Map ablaufen.

Wichtig finde ich hierbei, dass man, wenn man schon mit Tilemaps arbeitet, als Maßeinheit auch Tiles verwendet. Sollte man später auch nur ansatzweise etwas einbauen wollen, wie den Support unterschiedlicher Auflösungen, dann ist es nur von Vorteil, nicht auf Pixelebene zu arbeiten. Wenn die Map also 40x30 groß ist, dann hat sie auch eine Gesamtgröße von 40x30 Tiles.

Wenn man für sein Spiel weitere Anforderungen hat, wird evtl. ein 3-dimensionales Array verwendet (Ebenen) bzw. je Feld mehr als nur ein Verweis auf das jeweilige Tile gespeichert, Kollisionsinformationen hinterlegt o. ä. Das hängt aber davon ab, was tatsächlich erforderlich ist.
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

Werbeanzeige