Ergänzungen zu TSB
Extrabefehl MAP
Extrabefehl MAP

Ein Level-Screen in Ghost Valley
Bild 1: Ein Level in Ghost Valley
Als die Version 1.0 von Ghost Valley fertig war und die ersten begeisterten User das Spiel durchgespielt hatten, erhob sich doch der Wunsch nach ein paar Verbesserungen. Vor allem der Aufbau eines Level-Screens mithilfe von PRINT erschien vielen auf die Dauer zu langsam. Schon sprang dem Programmierer von Ghost Valley, Christian Nennewitz (@Omega), ein anderer User aus dem Forum64 bei (@1570) und schuf eine Routine für den Aufbau von Level-Screens, die ohne sichtbare Verzögerung funktionierte.

Da Ghost Valley auf Hires-Grafik verzichten kann und fast alle grafischen Elemente mit dem Zeichensatz erledigt, war der Ablageort für diese Routine (der Platz für die Farben einer Hires-Grafik an Adresse $C000) gerade richtig. Ghost Valley 2.0 war geboren.


Warum nicht so etwas als Befehl in TSB integrieren? @Omega (Christian Nennewitz) hat unübersehbar bewiesen, dass Basic-Spiele - zumal in TSB programmiert - richtig Spaß bereiten können! Da wäre ein neuer Befehl, der schnelle Level-Screens ausgibt, doch wirklich nützlich! Gesagt, getan.

Mit der Ausgaberoutine von @1570 als Vorlage war schnell der Befehl MAP erstellt. Er zeichnet 2×2-Kacheln (Tiles, gesammelt in einem Tile-Set) aus einem dafür erstellten Spiele-Zeichensatz auf den Bildschirm. Dabei verwendet er eine Vorlage, die die Positionen dieser Kacheln auf dem Screen wiedergibt, die eigentliche Map.

Der Ghost-Valley-Zeichensatz
Bild 2: Ghost-Valley-Zeichensatz
Genauso macht es auch der Befehl MAP: Ob der zugehörige Zeichensatz für den Hires-Modus oder Multi-Modus gedacht ist, ist egal. (Für den Multi-Modus müssen die Befehle, um ihn einzuschalten, nach der Screen-Ausgabe erfolgen.) Der Befehl nimmt als Code für die Kachel Null die Raute an ("#", Code 35) und braucht die vier Zeichen einer Kachel bereits in der Kachelanordnung (die vier Zeichen der Kachel müssen direkt aufeinanderfolgen). Die Kacheln müssen ab der Adresse $E200 im Speicher liegen (ab Zeichencode 64), was dazu führt, dass insgesamt höchstens 48 verschiedene Kacheln für einen Screen definiert werden können, dafür aber die alphanumerischen Zeichen für Textausgaben weiterhin zur Verfügung stehen (Bild 1, unten links). In Bild 2 sieht man den ganzen Zeichensatz für das Spiel Ghost Valley und erkennt gut oben rechts die Kachel für das Mauerwerk und rechts daneben die Kachel für die Türen (aus Bild 1).

Und wie funkioniert das mit den Farben? Gut, MAP färbt kachelweise ein, nicht zeichenweise. Dafür erwartet der Befehl ein Integer-Array, dimensioniert auf die Anzahl der Kacheln (also bis zu 48). Integer ist zwingend erforderlich, da der Befehl die Farben direkt aus dem Speicher ausliest und nur wissen muss, wo die Farb-Daten beginnen. Sollten die Farben etwas komplexer verteilt sein, nimmt man FCOL zuhilfe. Bei Multicolor verändert FCOL die individuelle Multifarbe des Zeichens (Bitmuster %11, Beispiel s. unten).

<nach oben>


Dies ist die Syntax von MAP:

MAP Zeile, Spalte, Kachel$, Farb-Array%(0)

MAP muss ausdrücklich ins TSB-System eingebunden werden, da es sich um einen Spezialbefehl handelt, der Platz belegt, der sonst auch anderweitig verwendet werden könnte (Extension). Er macht nur Sinn, wenn es darum geht, Spiele-Bildschirme schnell aufzubauen. Außerdem ist man bei einem Extension-Befehl ganz frei, ihn umzuprogrammieren und um weitere Features zu erweitern.

Folgende Basic-Zeilen aktivieren den Befehl MAP (der sich unter dem Namen "ext.map" auf der Disk befinden muss). Das TSB-System muss dazu mindestens die Versionsnummer 2.31113 aufweisen (lässt sich mit RETRACE feststellen).

100 if peek($cb00)=$ad then d!poke$897e,$caff
110 if d!peek($897e)<>$caff then load"ext.map",0,0,$cb00

Für Bild 1 ergäbe sich die folgende Screen-Vorlage (Map) von 20×10 Kacheln (ergibt 40×20 Zeichen), bei dem Beispiel handelt sich um Screen 3 in Level 5 von Ghost Valley, wo man am Drachen vorbei muss, um den gelben Schlüssel zu bekommen (im Bild ist das gerade schiefgegangen, denn der arme Prinz wurde soeben ein Opfer der Drachenflammen):

  Map:  6666666666%%%%%%%%%%   "6" ist Code 54 (das Wasser), "%" ist Code 37 (das Mauerwerk)
        6666%%%%%%%        %
        6666%  ?           %   "?" ist Code 63 und steht für ein im Spiel unsichtbares Signalzeichen
        %%%%%  ?           %
               %%%%  +++   %   "+" ist Code 43 (die grüne Hecke)
        &      %%%%%%%%%%%%%   "&" ist Code 38 (die Tür)
        %%%%%
        6666%        #         "#" ist Code 35 (die Baumkrone)
        6666%%%%%%%  $&    &   "$" ist Code 36 (der Baumstamm)
        6666666666%%%%%%%%%%   Hier nicht aufgeführte Zeichen aus Bild 1 sind Sprites.

Für die Farben muss jeweils der Wert 35 von den Codes abgezogen werden, damit die Position im Farb-Array stimmt. Für das Wasser ergibt sich 54 - 35 = 19, d.h. wenn das Array den Namen co% hat, wird an Position co%(19) der Wert 6 (blau) eingetragen, und für das Mauerwerk kommt 37 - 35 = 2 heraus, nach co%(2) muss der Wert 2 (rot) geschrieben werden.

In Ghost Valley hat @Omega folgende Variablen festgelegt:
- ma$(4,10): die vier Screen-Maps pro Level, Feldindex 0 wird nicht verwendet
  (vier Screens mit je zehn Kachelzeilen)
- co%(48): die Farben der 48 Kacheln, Feldindex 0 wird auch hier nicht verwendet
- nr%: Nummer der aktuellen Level-Map ma$ (in Bild 1 - Level 3 - ist das nr%=3)

Hier die Routine, die alle vier Level-Maps einliest. Die Daten dafür beginnen in Zeile 12720, Screen 3 liegt an Zeile 12940 (hier weggelassen, die Werte haben wir ja oben schon gezeigt):

   12630 rem ----------
   12640 proc mapdaten
   12650 reset12720                   Beginn der DATA-Zeilen für die vier Screen-Maps
   12660 for i=1 to 4                 Vier Maps...
   12670 : for j=1 to 10              ...zu je 10 Kachelzeilen
   12680 :   read ma$(i,j)
   12690 : next j
   12700 next
   12710 rem -screen 01-------
   12720 data " #  '?     ?'    '?&"
   12730 data " $@ '?  ?  ?' #c '? "

Und die Routine, die eine ganze Screen-Map (blitzschnell) ausgibt, sieht so aus:

   920 rem ----------
   930 proc map
   940 spritesaus04567                Sprites erstmal aus
   950 bloeschen
   960 for i=1 to 10                  10 Kachelzeilen ausgeben
   970 : map (i-1)*2,0,ma$(nr%,i),co%(1)
   980 next i
   990 end proc

Da die Array-Indizes 0 in Ghost Valley nicht benutzt werden, gibt man hier beim MAP-Befehl den Ausgangspunkt der Farben mit Index 1 statt 0 an: co%(1). Die interne Berechnung durch MAP geht nämlich davon aus, dass Index 0 verwendet wird (dann müsste man co%(0) angeben). So könnte man auch mehrere verschiedene Farblisten erstellen: Das Farb-Array entsprechend groß machen und im MAP-Befehl den Basiswert für die jeweilige Farbliste angeben (1, 49..., hier also: 1).

Damit der MAP-Befehl nun die richtigen Bildschirmzeilen trifft, helfen wir mit der Multiplikation mit 2 nach (wir brauchen für die Zeilen den doppelten Wert der Laufvariablen, hier also 0 bis 18 in Zeile 970: (i-1) mal 2). Man kann solche Screens nach der Ausgabe durch MAP natürlich noch zusätzlich (mit FCOL) nachfärben, wie man ganz oben auf dieser Seite im Titelbild oder bei den hier unten folgenden Beispielen sehen kann.

<nach oben>


Zu Demonstrationszwecken haben wir nämlich eine Diskette zusammengestellt, auf der sechs solcher Screen-Maps und ein zugehöriger Viewer zu finden sind, hauptsächlich aus Material entnommen, das dem PC-Programm CharPad der englischen Firma Subchrist beiliegt. Wir sind nicht ganz sicher, ob es sich dabei um Zeichensätze aus kommerziellen Spielen handelt, weil wir jeweils nur wenige Informationen recherchieren konnten. Ein siebtes Bild (in Multicolor) wird wegen des anderen Modus mit einem anderen Viewer angezeigt.

Die Screen-Maps und deren TSB-Darstellungsprogramme auf der Diskette sollen aber auf jeden Fall zeigen, wie gut der MAP-Befehl auch Basic-Programme dazu befähigt, beeindruckende Spieleszenarien zu entwickeln. Eine große Hilfe beim Umsetzen der CharPad-Daten nach TSB war auch das großartige C64Studio von Georg Rottensteiner (@Endurion), mit dem wir die Zeichensatzdefinitionen, Tile-Sets und Farbinformationen erfolgreich nach TSB konvertieren konnten (TSB selber war natürlich auch sehr hilfreich, s. die Make-Hilfsprogramme auf unserer Disk).

Jetzt Screenshots von unserem Viewer-Programm "testmaps" auf der unten auf dieser Seite downloadbaren Demo-Disk für den neuen TSB-Befehl MAP. Im Folgenden zunächst ein Beispiel aus dem (unveröffentlichten?) Spiel "Danger Castle", an dem Saul Cross beteiligt war:

Danger Castle
Ein weiteres Beispiel ist ein Screenshot aus dem Spiel Kirby's Dreamland (ursprünglich für Nintendo):

Kirby's Dreamland
Und schließlich noch ein Screenshot, von dem ich nur den Titel des Bildes, aber nicht das dazugehörige Spiel kenne ("Icehouse"):

Icehouse
Abschließend ein Beispiel für einen Screen im Multicolor-Modus. Er stammt aus einem Pacman-Klon namens "Platman Worlds":

Platman

Alle diese Screenshots kann man sich nacheinander auf dieser Diskette anschauen: D64 downloaden, TSB starten und dann eins der Programme "testmaps" oder "multimap.dmo" laden und starten.

<nach oben>