Char Pad: Tilemaps erstellen & anzeigen

weitersagen ...
Tweet about this on TwitterShare on FacebookShare on Google+Share on LinkedIn

CBM prg Studio
Mit Char Pad einen Level erstellen und im Programm anzeigen

Eine häufig genutzte Methode um Levelkarten zu erstellen, ist die Verwendung von Tiles. Dabei werden aus einzelnen Zeichen größere ‚Bauteile‚ (die Tiles) erstellt, um aus diesen dann wiederum den Level zusammenzubauen.
Das CBM prg Studio bietet zwar Editoren, um Zeichensätze und ganze Bildschirme zu erstellen, aber für Tiles fehlt die Unterstützung. Beim C64 Studio gibt es einen Mapeditor, der sagt mir allerdings nicht sonderlich zu.

Ein sehr beliebtes Tool, um Zeichensätze, Tiles und Tilemaps zu erstellen, ist das Char Pad (hier findet ihr übrigens auch das ebenfalls beliebte Sprite Pad).

 

Für den Programmierteil solltet ihr euch schon mit den Beiträgen ‚VIC-II: Speicherbereiche festlegen‚ und ‚VIC-II: Grafikmodes – Text‚ beschäftigt haben.

 

Char Pad: Crashkurs
Zunächst solltet ihr euch das Char Pad herunterladen. Das Programm muss nicht installiert werden, ihr könnt es einfach entpacken und schon ist es einsatzbereit. Sobald alles entpackt ist, startet das Char Pad direkt mal.

Das Char Pad
Das Char Pad

 

Werfen wir nun einen Blick auf einige wichtige Einstellungen.

CharPad_002

  1. Begebt euch zum Tiles-Tab.
    Hier werden die einzelnen Tiles (Bauteile) erstellt und verwaltet.
  2. Dies ist der Editor, in dem ihr eurer Tiles am Stück zeichnen könnt.
  3. Das ist die Liste mit eueren Tiles.
  4. Hier seht ihr die einzelnen Zeichen, aus denen die Tiles zusammengebaut werden.
     
    Die Tiles im Char Pad können 1×1, 2×2, 3×3, 4×4 oder 5×5 Zeichen groß sein. Als erstes solltet ihr euch also überlegen, welche Tilegröße ihr benötigt und diese einstellen.CharPad_003
  5. Tilegröße festlegen
  6. und übernehmen
    CharPadAni_01Wie ihr seht, ändern sich alle drei Anzeigefenster abhängig von der gewählten Größe.
     
    CharPad_004
  7. Hier legt ihr fest, wie die Farben vergeben werden sollen. Das schauen wir uns gleich genauer an.
  8. Entscheidet euch für einen Multicolor oder ‚einfachen‚ Zeichensatz.
  9. Mit diesem Haken könnt ihr die Hilfslinien an- und abschalten.
     
    Ich nehme nun eine Tilegröße von 4 und entscheide mich für einen Multicolor Zeichensatz.
    Um die drei verschiedenen Farb-Einstellungen (7.) zu untersuchen wähle ich zunächst ‚Global‚ und zeichne zwei einfache Muster mit der Hauptfarbe ‚Pen – RAM Colour‚.
    CharPad_005Im Editor (2.) seht ihr das aktuell gewählte Tile aus dem Tile Set (3.). Das Schöne am Char Pad ist, dass ihr direkt im Editor euer großes Tile zeichnen könnt. Das große Bauteil wird dabei automatisch auf einzelne Zeichen verteilt. Diese findet ihr ganz rechts im Character Set (4.).
     
    Nun aber zu den Farben:
    Die beiden Multicolor-Farben sind, wie ihr wisst, immer für alle Zeichen identisch. Genau das Gleiche gilt auch für die Hauptfarbe, wenn ihr ‚Global‚ auswählt.
    CharPad_006
  10. Ändern wir die Farbe ‚Pen – RAM Colour‚ von grün auf gelb, dann ändert sich direkt die Farbe aller Tiles.
     
    CharPad_007
  11. Denkt daran, dass ihr bei Multicolor auch hochauflösende Zeichen verwenden könnt. Klickt ihr bei aktivem Multicolor eine Farbe aus der oberen Reihe an, dann verdoppelt sich die Auflösung in X-Richtung im Editor.
     
    Ändert nun die Einstellung unter ‚RAM colouring‚ (7.) auf ‚Per Tile‚. Ab jetzt könnt ihr für jedes einzelne Tile eine Farbe vergeben.
    CharPad_008Lasst euch nicht davon irritieren, dass sich auch die Farbe aller Zeichen ganz rechts (4.) ändert! Dies ist normal und hat keine Auswirkung auf den Export.
     
    Werfen wir abschließend noch einen Blick auf die letzte Einstellung von ‚RAM colouring‚ (7.) ‚Per Tile Cell‚.
    CharPad_009
  12. Wie ihr seht, könnt ihr mit dieser Einstellung Farben für jede einzelne Zelle des Tiles vergeben. Außerdem steht euch dann noch eine dritte Hilfsfunktionen zur Verfügung.
    Cell Selector‚: Zellen des Tiles markieren, um Material oder Farben am Block zu setzen.
    Cell Marker – Material‚: Hiermit könnt ihr zusätzliche Kennzeichen zum Tile angeben, auf die ihr dann im Programm reagiert. Damit könnt ihr z. B. allen Stellen des Tiles, die ‚tödlich‚ sind die Nummer 1 zuweisen. Im Source müsst ihr dann nur kontrollieren, ob der Spieler ein Tile-Zeichen mit dem Material 1 betreten hat, anstatt auf zig verschiedene Zeichencodes zu prüfen.
    Cell Marker – RAM colour‚: Damit ändert ihr die Farbe der einzelnen Zellen.
     
  13. Compress options
    Durch einen Klick auf Compress könnt ihr doppelte Zeichen entfernen lassen. Normalerweise legt das Charpad für jedes Tile eigene Zeichen an.
    CharPad_010Hier seht ihr, dass das erste und dritte Tile, bis auf die Farben in der Mitte, eigentlich identisch sind. Trotzdem werden rechts (4.) die Zeichen für die beiden Tiles doppelt angezeigt. Klickt ihr nun auf ‚Compress‚ (13.) und habt die Haken wie auf dem Bild gesetzt, dann verschwinden fast alle doppelten Zeichen.
    CharPad_011Es bleiben jetzt nur noch die Tiles mit einer abweichenden Farbe übrig. Selbst diese können wir noch zusammenfassen. Dazu müssen wir nur den Haken bei ‚Copy colours to character attributes‚ entfernen.
    CharPad_012Hiermit könnt ihr also die benötigten Zeichen reduzieren.
     
  14. Wechselt nun zum Tab ‚Map‚
    CharPad_013Hier auf diesem Tab baut ihr nun, aus den eben erstellten Tiles, euren Level.
     
  15. Der große Bereich in der Mitte ist euer Map-Editor.
  16. Die verfügbaren Tiles findet ihr rechts in der Liste.
  17. Legt hier die größes eures Ausgabebildschirms fest. Beim C64 also 40×25.
  18. Hier gebt ihr an, wie groß die Map werden soll. Ihr könnt für scrollende Spiele oder für Spiele bei denen der Bildschirm umgeschaltet wird, auch Maps erstellen, die größer als der Bildschirm sind. Gebt hier einfach die Karten größe als Tiles x Tiles an. Hier findet ihr auch den Speicherbedarf eurer Map.
  19. Natürlich könnt ihr eure Arbeit auch speichern. Klickt dazu auf den Menüpunkt File und wählt ‚Save Project As…‚ aus.
    CharPad_014Das Programm speichert sämtliche Änderungen (Zeichensatz, Tiles, Map…).

Unter ‚File‚ (19.) findet ihr auch das Gegenstück -> ‚Open Project…‚. Diesen Menüpunkt verwenden wir jetzt, um ein mitgeliefertes Beispiel zu öffnen. Klickt also auf ‚Open Project…‚ und begebt euch im folgenden Dialog ins ‚Char Pad‚ Verzeichnis. Dort gibt es den Ordner ‚Examples‚ und darunter ‚Metal Warrior – 4×4‚. Wählt dann die Datei MW - L1.ctm aus.
CharPad_015 CharPad_016
Schaut euch mal die Tiles und die Map in Ruhe an.

 

Wir wollen nun ein Programm schreiben, dass diese Daten verarbeiten kann, bzw. zumindest den ersten Bildschirm anzeigt. Dazu müssen wir erstmal alle benötigten Daten exportieren. Wählt unter ‚File‚ (19.) den Punkt ‚Export Data…‚ aus.
CharPad_017

  1. Unter ‚Export Items‚ legt ihr fest, welche Daten ihr braucht. Wir nehmen hier alle.
  2. Für die Attribute (Farben) müssen wir festlegen, wie diese exportiert werden sollen. Wir wählen hier ‚Per Tile‚. Wie ihr oben seht, wurde diese Einstellung auch unter ‚Tiles – RAM colouring‚ gewählt. Die Einstellung wirkt sich auf die Größe der ‚Attribute Table‚ aus.
  3. Hier seht ihr den Speicherbedarf für die einzelnen Dateien.
  4. Wir wählen für den Export das ‚Raw Data‚-Format, da wir nur die reinen Daten, ohne eine Ladeadresse benötigen.
     
    Nach einem Klick auf OK werdet ihr nach den Dateinamen für die einzelnen Files gefragt. Ich belasse es für unser Beispiel bei den vorgeschlagenen Namen: chars.raw, tiles.raw, map.raw und attribs.raw.

Bevor wir nun anfangen unser Programm zu schreiben, sollten wir erstmal klären, wie die Dateien aufgebaut sind und wie sie zueinander in Bezug stehen.

 

Aufbau der Daten
Wir haben nun also unsere vier Dateien: chars.raw, tiles.raw, map.raw und attribs.raw. Deren Namen sagen eingentlich schon wo sich was befindet, aber hier nochmal als Grafik:

CharPad_X_00Wir lesen gleich aus der  map.raw die Tile-Nr. aus. Diese ist ein BYTE groß. Dabei müssen wir beachten, dass die Map 100 Tiles breit ist, wir aber nur 10 Tiles brauchen, um die gesamte Bildschirmbreite auszufüllen. Die Höhe der Map beträgt 15, wovon wir nur 5 für die Bildschirmhöhe benötigen.
Mit der Tile-Nr. aus map.raw, schauen wir in  tiles.raw nach (Pfeil 1), wie das Tile aufgebaut ist. Dort finden wir die einzelnen Zeichen (Pfeil 2), aus denen das Tile besteht. Alle 16 Zeichen (wir haben hier 4×4 große Tiles) sind dort hinterlegt (s. Tile-Nr. 25). Diese Zeichen entsprechen einfach unseren Screencodes aus der Datei chars.raw (Pfeil 3 & 4).

Bleiben noch die Farben:
In der Datei  attribs.raw werden die Farben exportiert. Der Aufbau hängt von euren Farb- und Exporteinstellungen ab.

Attribute Table – Per Tile
Hier wird für das gesamte Tile ein Farb-BYTE in die attribs.raw geschrieben. Die Farbe könnt ihr dann ganz einfach mit der Tile-Nr. aus dieser Datei auslesen.
Dateigröße in BYTEs = Anzahl der Tiles (hier 128 BYTEs)

Attribute Table – Per Tile Cell
Hier wird für jede Zelle des Tiles eine eigene Farbe nach attribs.raw geschrieben. Der Aufbau der Datei ähnelt dann dem der tiles.raw. Ihr könnt einfach parallel zum jeweiligen Zeichencode die Farbe aus der  attribs.raw  lesen.
Dateigröße in BYTEs = Anzahl Tiles * Tile size² (hier 128*4*4 = 2048 BYTES)

Attribute Table – Per Character
Bei dieser Exportmethode wird für jedes Zeichen eine Farbe in die Datei  attribs.raw  geschrieben. Ihr könnt also mit dem Zeichencode auf die attribs.raw zugreifen.
Dateigröße in BYTEs = Anzahl der Zeichen (hier 256)

Einen Sonderfall stellt das RAM colouring – Global dar.
Da hier für alle Zeichen die selbe Farbe verwendet wird, brauchen wir die attribs.raw eigentlich nicht. Die Farbe können wir direkt für alle Zeichen ins Farb-RAM kopieren.

Wo findet man das ‚Material‚?
Möchtet ihr die ‚Material‚-Möglichkeit nutzen, dann fragt ihr euch evtl. wie die Datei heißt, in der diese Daten stehen. Man nutzt hier den Umstand aus, dass der C64 nur 16 Farben beherrscht. Daher wird für das Farb-BYTE nur das untere Nibble benötigt. Das ‚Material‚ findet ihr also in der attribs.raw im oberen Nibble des jeweiligen Farb-BYTEs.

 

Programmerstellung
Wir sollten erstmal überlegen, wie unser Programm arbeiten muss.

  • VIC-II – Speicheraufteilung vornehmen
  • Multicolor-Textmodus aktivieren und MC-Farben setzen
  • Den Bildschirm mit 10 x 5 Tiles füllen. Dies entspricht 40 Zeichen und 20 Zeilen.

Den Anfang machen einige Konstanten…

Diese halten das Programm flexibel, sodass man später leichter andere Map- / Tilegrößen verarbeiten kann.

Die ersten beiden Punkte aus der obigen Liste sollten für euch eine Kleinigkeit sein…

Wir löschen hier einfach mal kurz den Bildschirm, setzten die bekannten Farben und nehmen die oben erwähnten Einstellungen vor. Dann wird zu drawmap gesprungen, um die Karte zu zeichnen. Zum Schluß bleibt das Programm in einer Endlosschleife hängen.

Die aus dem Char Pad exportierten Daten binden wir direkt in unser Programm ein. Dabei machen wir es uns für dieses Beispiel recht einfach und legen die Daten des Zeichensatzes ‚chars.raw‚, direkt an der von uns gewählten Adresse $2000 ab. Damit sparen wir uns das Kopieren des Zeichensatzes. Fügt also, hinter der Endlosschleife, die nächsten Zeilen ein.

 

Bildschirm zeichnen
Um jetzt den gesamten Bildschirm zu füllen, brauchen wir 10 Tiles für die Breite. Ein Tile ist hier vier Zeichen breit, macht also 40 Zeichen, genau unsere Bildschirmbreite beim C64. Für die Höhe werden nur 5 Tiles (= 20 Zeilen) benötigt. Schaut euch die Karte nochmal im Map-Editor an. Sie enthält übereinander drei Abschnitte der Strecke. Der Level ist also in Wirklichkeit eigentlich 300 Tiles (also 30 komplette Bildschirme) breit und 5 Tiles hoch.

Hier könnt ihr auch einen Vorteil der Tile-Technik erkennen. Wie ihr beim Export gesehen habt, benötigen wir 2048+2048+1500+128=5724 BYTEs für den Level. Würdet ihr immer ganze Bildschirme mit einzelnen Zeichen verwenden, dann bräuchten wir 2048+40*20*2*30=50048 BYTEs (Zeichensatz+Bildschirmbreite*Bildschirmhöhe*2 für Screen & Color-RAM*Levelbreite in Bildschirmen), also mehr als neunmal soviel!

Der Einfachheit halber zerlege ich das ‚Problem‚ in zwei Teile. In der Funktion drawmap wird die Datei map.raw ausgelesen. Hier wird also immer das nächste Tile gesucht. Dieses wird dann an die zweite Funktion drawtile übergeben, die das Tile endgültig auf den Bildschirm bringt. Der folgende Source dient wieder nur als erstes Beispiel und läßt viel Raum für Verbesserungen. Es wird nur der erste Bildschirm der Map dargestellt, ihr könnt das Programm später ja noch verbessern. Beginnt also direkt hinter der Endlosschleife jmp * mit den beiden Funktionen.

Zu Beginn holen wir uns die Adresse, an der die  map.raw  im Speicher liegt und merken uns diese auf der Zeropage.

Dann verwenden wir zwei Hilfsvariablen auf der Zeropage als Schleifenzähler. In ZP_TILESY beginnen wir die Tilezeile (Y-Richtung) von 0 an hochzuzählen. In ZP_TILESX zählen wir die Anzahl der Tiles in X-Richtung herunter. Dann holen wir hinter @loop1 zunächst die X-Position des Tiles ins Y-Register. Damit holen wir uns jetzt per Y-nach-indizierter-Adressierung aus der Map die nächste Tile-Nr.

CharPad_018Dann springen wir mit der Tile-Nr. nach drawtile. Sobald wir von dort zurückkehren, verringern wir ZP_TILESX, um das nächste Tile in dieser Zeile zubekommen. Solange ZP_TILESX positiv ist, springen wir wieder nach @loop1. So arbeiten wir erstmal rückwärts alle Tiles in der Zeile ab.

Haben wir die gesamte Zeile von rechts nach links ausgegeben, dann müssen wir zum Anfang der nächsten Zeile ‚springen‚. Dazu addieren wir zu unserer Hilfsadresse ZP_MAPADR einfach die Breite der Map. Also MAPWIDTH in den Akku holen, Carry-Flag löschen, zu ZP_MAPADR addieren und wieder zurückschreiben. Dann noch das C-Flag zum MSB addieren. Danach erhöhen wir ZP_TILESY (unseren Zähler für die Zeilen) und prüfen, ob dieser die Anzahl der Tiles in Y-Richtung  SCREENTILES_Y für die Bildschirmausgabe erreicht hat. Falls nicht, geht es zurück nach @loop, um die nächste Zeile auszugeben. Zum Schluß wird die Funktion einfach verlassen.

Nun ist unsere eben bereits gesehene Funktion drawtile an der Reihe. Hier möchte ich nicht nur die Berechnung der Positionen zur Laufzeit zeigen, sondern eine Alternative anbieten. Wir beschleunigen unsere Funktion etwas, indem wir Hilfstabellen benutzen.

In  ZP_TILENO merken wir uns die aktuelle Tile-Nr. Dann machen wir es uns ganz einfach! Die in  ZP_TILESY stehende Y-Position des Tiles in der map.raw nutzen wir auch für die Ausgabe. Dies klappt so natürlich nur für den ersten Bildschrim, wenn wir ihn ganz links beginnen. Hier besteht also für euch Handlungsbedarf, wenn ihr die Routine später weiterverwenden möchtet. Die Position holen wir ins Y-Register und lesen damit aus unserer Hilfstabelle screenrow_lsb das LSB für die aktuelle Zeile. Dieses speichern wir in  ZP_SCREENADR für den Bildschirmspeicher und in  ZP_COLORRAMADR für das Color-RAM. Dann holen wir uns das MSB aus der Tabelle screenrow_msb und speichern es bei ZP_SCREENADR+1.

Um nun die korrekte Startadresse zu berechnen, müssen wir natürlich noch wissen, an welcher X-Position die Ausgabe beginnen soll. Wir nutzen hier wieder den Wert, der auch in drawscreen genutzt wurde und lesen die X-Position  ZP_TILESX ins X-Register ein. Damit holen wir dann den Offset vom linken Rand aus der Hilfstabelle screencol_offset. Diesen Wert müssen wir dann noch zu unserer Startadresse ZP_TILESX addieren. Auch hier speichern wir fürs Farb-RAM das LSB ebenfalls in ZP_COLORRAMADR. Sobald wir die Startadresse berechnet haben, müssen wir noch das MSB für das Farb-RAM anpassen. Nach  sta ZP_SCREENADR+1 ;und speichern befindet sich im Akku das MSB für den Bildschrimspeicher. Da wir diesen fest bei $0400 gelassen haben, müssen wir nur $D4 addieren, um den Beginn des Color-RAMs $D800 zu erhalten. Das MSB speichern wir dann natürlich bei ZP_COLORRAMADR+1.

Jetzt müssen wir natürlich noch ermitteln, wo die Zeichendaten für das aktuelle Tile beginnen. Dazu merken wir uns die Staradresse der Tiles in ZP_TILEADR auf der Zeropage. Anschließend holen wir uns die aktuelle Tile-Nr. aus ZP_TILENO ins X-Register und prüfen, ob die Nr. gleich Null ist. Falls ja, müssen wir keinen Offset berechnen und springen nach @skip. Ist die Tile-Nr. aber gößer Null, dann addieren wir in einer Schleife immer die Tilegröße TILESIZE zur Startadresse der Tiles in ZP_TILEADR. Dieser Punkt sollte unbedingt überdacht werden! Ihr könnt z. B. wie in ‚MUL & DIV (Ganzzahl)‚ beschrieben, die Multiplikation verwenden oder ihr greift erneut auf eine Hilfstabelle zurück (das zeige ich gleich nochmal mit dem C64 Studio, da dort schönere Möglichkeiten für das Erstellen von Tabellen zur Verfügung stehen).

Jetzt können wir mit der Ausgabe beginnen.
Noch mal zur Erinnerung:

  • ZP_SCREENADR : Startadresse der aktuellen Zeichenzeile für die Bildschirmausgabe
  • ZP_COLORRAMADR : Startadresse der aktuellen Zeichenzeile im Farb-RAM
  • ZP_TILEADR : Startadresse der aktuellen Tilezeile ab tiles
  • ZP_TILENO : aktuelle Tile-Nr.

Als Letztes merken wir uns nun in ZP_TILEHEIGHT noch die Tilehöhe TILEHEIGHT. Dann holen wir uns hinter @loop1 die Tilebreite TILEWIDTH ins Y-Register. Bei @loop2 holen wir uns das nächste Tile-Zeichen ZP_TILEADR in den Akku und geben es auf den Bildschirm aus ZP_SCREENADR. Dann brauchen wir noch die Farbe, also holen wir uns die aktuelle Tile-Nr.  ZP_TILENO ins X-Register. Da wir uns beim Export für ‚Attribute Table – Per Tile‚ entschieden haben, können wir die Farbe direkt ab colors mit der Tile-Nr. auslesen. Die so ermittelte Farbe kopieren wir dann ins Farb-RAM. Danach verringern wir das Y-Register und wiederholen den Block @loop2, solange es positiv ist.

Sobald die komplette Zeile des Tiles verarbeitet wurde, müssen wir noch den Beginn der nächsten ermitteln.

Beginnen wir mit der Bildschirm- & Color-RAM-Adresse. Da die Bildschirmausgabe (und damit auch das Farb-RAM) 40 Zeichen breit ist, holen wir und die 40 erstmal in den Akku. Dann löschen wir das C-Flag für die Addition und addieren den Wert auf das LSB der Bildschirmadresse an ZP_SCREENADR. Das Ergebnis schreiben wir wieder zurück und übernehmen es auch für das LSB des Farb-RAMs ZP_COLORRAMADR. Dann addieren wir noch das eventuell gesetzte Carry-Flag zum MSB der Bildschirmadresse ZP_SCREENADR+1 und addieren anschließend noch den Offset $D4 für das MSB des Farb-RAMs ZP_COLORRAMADR+1.

Außerdem müssen wir auch noch den Beginn der nächsten Zeichenzeile des Tiles ZP_TILEADR erhöhen.

Dazu addieren wir nach bekanntem Muster einfach die Tilebreite TILEWIDTH zur Tileadresse ZP_TILEADR. Abschließend verringern wir die Tilehöhe in ZP_TILEHEIGHT um eins und springen, solange dies nicht Null ist, wieder nach @loop1. Ansonsten wird die Funktion verlassen.

Das wars auch schon, jetzt brauchen wir nur noch unsere Tabellen.

Wie ihr seht, nehmen wir für screenrow_... einfach die Startadresse des Bildschirmspeichers und addieren für jede Tilezeile 40*TILEHEIGHT (hier also 160) hinzu. Da wir nur fünf Tilezeilen (zu je 4 Zeichenzeilen) benötigen, reichen hier fünf Adressen. Das CBM prg Studio erlaubt leider nur einen Operator je Zeile, deshalb müssen wir die Werte fest vorgeben oder umständlich mit Hilfskonstanten arbeiten. Einen schöneren Weg, die Tabellen zu erzeugen, zeige ich gleich mit dem C64 Studio.

In screenrow_... steht also an welcher Adresse die jeweilige Tilezeile beginnt. In der Breite benötigen wir 10 Tiles (zu je 4 Zeichen). Also legen wir in der Tabelle screencol_offset einfach den Offset vom linken Rand ab. Dazu müssen wir nur TILEWIDTH mit der jeweiligen X-Position (die Zählung beginnt bei 0) des Tiles multiplizieren.

Jetzt sollte sich das Programm erstellen lassen und auf dem Bildschirm der erste Screen erscheinen.

Unser Ausgabe
Unser Ausgabe

 

C64 Studio
Tabellen mit dem C64 Studio

Wie schon angedeutet, läßt sich obige Routine durch die Verwendung von Tabellen noch weiter optimieren. Leider unterstützt einen das CBM prg Studio dabei nicht sonderlich gut. Daher will ich hier mal kurz mit dem C64 Studio zeigen, wie es ‚besser‚ geht. 😉

Schauen wir uns erstmal an, wie man die Tabellen screenrow_... und screencol_offset eleganter erzeugen kann. Das C64 Studio bietet neben der Möglichkeit, komplexe Berechnungen auszuführen, auch noch Schleifen an, mit denen man ganz einfach Tabellen aufbauen kann.

Wie ihr seht verwenden wir für screenrow_... einfach jeweils eine !FOR-Schleife, die von 0 bis SCREENTILES_Y minus 1 geht und berechnen dann mit dem Schleifenwert row das LSB & MSB für die Startposition. Für screencol_offset machen wir es im Prinzip genauso. Statt manuell zehn BYTE-Anweisungen einzugeben, verwenden wir eine Schleife und berechnen die Werte bei der Programmerstellung.

Der Vorteil liegt auf der Hand. Wenn wir eine andere Tilegröße verwenden, brauche wir nur die Konstanten zu ändern und schon werden die Tabellen korrekt erzeugt.

Hier nun das komplette Listing für das C64 Studio, ich habe dort noch eine weitere Tabelle tilepos_... eingebaut. Diese enthält die Startadresse des Tiles ab dem Label tiles. Dann brauchen wir nicht mehr umständlich zu rechnen, sondern können einfach mit der Tile-Nr. aus ZP_TILENO auf die Tabelle zugreifen und das LSB & MSB holen. Schaut euch die Funktion drawtile mal genauer an.


So nun könnt ihr mal weiter daran arbeiten, eure Tilemaps auf den Bildschirm zu bringen. Wie bereits gesagt, hier sind noch einige Verbesserungen nötig bzw. ratsam. Versucht erstmal das Programm an andere Map- und Tilegrößen anzupassen. Exportiert auch mal die Farben in einem anderen Format und ändert das Programm. Dann solltet ihr euch überlegen, wie ihr z. B. einen beliebigen Ausschnitt der Map auf den Bildschirm bringt. Zu guter Letzt stehen natürlich auch noch Punkte wie Bildschirmumschaltung oder Scrolling auf dem Programm.

Es gibt viel zu tun, pac… ihr wisst schon 😉 .


Schrott!!Naja...Geht so...Ganz gut...SUPER! (2 Bewertungen | Ø 5,00 von 5 | 100,00%)

Loading...


 

<<< zurück |

weitersagen ...
Tweet about this on TwitterShare on FacebookShare on Google+Share on LinkedIn

7 Gedanken zu „Char Pad: Tilemaps erstellen & anzeigen“

  1. Mal eine Frage:

    Wieviel Rasterzeit benötigt deine Routine?
    Ich bin selbst aktuell daran eine Tile-MAP Darstellung zu programmieren (bin Anfänger). Aktuell verbrät meine Routine ca. 100 Rasterzeilen für eine Darzustellen Tilezeile (2×2 CharTiles bei 50 Tiles breitem Screen (ein „virtueller Screen mit 50×30 Zeichen)).
    Deswege würde mich mal interessieren, wie deine läuft…

    1. Hi,
      da der Beitrag nur das Prinzip verdeutlichen soll, habe ich die Rasterzeit nie beachtet / berechnet. Da hier also die Geschwindigkeit nicht im Vordergrund stand, würde ich das Ganze, für den Praxiseinsatz, nochmal überdenken. Ich kann jetzt auch nicht mit Zeiten aus anderen Projekten dienen, sorry.
  2. Um beim Thema zu bleiben: was wäre eine effiziente Methode herauszufinden „wo“ auf dem Bildschirm eine Kollision, zB zwischen einem Sprite und einem Char mit dem Material $F stattgefunden hat?

    Rechnet man die X,Y Sprite Position bei Laufzeit um, in Char Zeile/Spalte? Dann wenn eine Kollision stattfindet, weiss man anhand von Zeile/Spalte in der Map, um welchen Char es sich handelt, und mit dem Wert in den Attribs lesen, ob das Material, msb, von diesem Char gesetzt ist?

    Das scheint mir ein langer weg. Vielleicht geht es einfacher. 🙂

    1. Eine Umrechnung der Sprite-Position brauchst du. Dabei kannst du natürlich wieder auf Tabellen zurückgreifen.

      Wie man mit diesen Infos weiter verfährt, hängt nun davon ab, wie die Map aufgebaut ist und wie sie verwendet wird.
      Du kannst das Material beim Char Pad z. B. in die einzelnen Zeichen kopieren lassen und dann als Attribute exportieren. Dann kannst du mit dem über die Sprite-Position ermittelten Zeichencode einfach darauf zugreifen.

      Verwendest du eher statische Bildschirme, kannst du z. B. auch eine Kollisionsmap einsetzen. Dazu kopierst du die Attribute / das Material parallel zum Color-RAM in einen weiteren Speicherbereich und kontrollierst dort mit der berechneten Zeichenposition welches Attribut vorliegt.

      Natürlich kann man auch vom Zeichen ‚zurück‘ über das Tile zum Attribut / Material gehen, das ist aber schon sehr umständlich.

      1. Vielen Dank für die Info. Ich werde deinen Vorschlag ausprobieren eine separate Kollisionsmap aufzustellen. (die neue Benennung der ZP-Konstanten ist auch jetzt ganz klar, danke) 😉

  3. Super Tutorial, wie immer. Sehr komplett und hat viele offene Fragen beantwortet. Ich gebe es aber zu, erst beim zweiten Anlauf alles verstanden zu haben, da ich mich immer wieder in den ähnlich benannten Konstanten verlor (ZP_Adr/Help1,2,3..). Mit doppelter Konzentration ging es aber. 😉

    1. Man wächst mit seinen Aufgaben 😉

      War mir beim Schreiben auch schon bewußt, dass diese Namensgebung ‚grenzwertig‘ ist.
      Habe mich jetzt für andere Namen entschieden und hoffe damit wird es etwas lesbarer.

Schreibe einen Kommentar


Beachtet bitte, dass ich eure Kommentare erst manuell freigegeben muß, bevor sie auf der Seite erscheinen! Da ich nicht pausenlos am Rechner sitze, kann es schon mal etwas dauern, bis ein Kommentar für alle sichtbar ist.

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Protected by WP Anti Spam