Programmierung_eines..

Transcription

Programmierung_eines..
Programmierung eines 2D
Computerspiels
mit GLBasic
von Sebastian Mieruch
[email protected]
Inhaltsverzeichnis
Abbildungsverzeichnis
II
1 Einführung
1
2 GLBasic
2
3 Grundlegendes
2
4 Aufbau des Artikels
2
5 Start
3
6 Erstellung des Quellcodes
6.1 Initialisierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.2 Hauptschleife . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
I
4
4
13
Abbildungsverzeichnis
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Spieloberfläche von Jamaicat
Alle Grafiken für Jamaicat .
Initialisierung . . . . . . . . .
Initialisierung . . . . . . . . .
Initialisierung . . . . . . . . .
Sub intro . . . . . . . . . . .
Startbildschirm . . . . . . . .
Initialisierung . . . . . . . . .
Sub nextlevel . . . . . . . . .
Sub gewonnen . . . . . . . . .
Initialisierung . . . . . . . . .
Hauptschleife . . . . . . . . .
Sub music . . . . . . . . . . .
Sub level . . . . . . . . . . . .
Sub jamaicat . . . . . . . . .
Sub jamaicat . . . . . . . . .
Sub jamaicat . . . . . . . . .
Sub einsammeln . . . . . . . .
Sub gegner1 . . . . . . . . . .
Sub gefangen . . . . . . . . .
Sub gegner2 . . . . . . . . . .
Sub gegner vom typ3 . . . . .
Sub leben . . . . . . . . . . .
Sub verloren . . . . . . . . . .
Sub vogel . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
II
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
1
3
4
6
7
8
8
9
10
11
12
13
14
15
15
16
17
19
20
21
22
23
24
24
25
1
Einführung
In diesem Artikel wird ein einfaches Computerspiel mit der Programmiersprache GLBasic
erstellt. Es handelt sich dabei um ein Geschicklichkeitsspiel. In Abb. 1 ist ein Screenshot
der Spieloberfläche zu sehen. Der schwarzumrandete Kasten ist der sichtbare Bildschirm
Abbildung 1: Spieloberfläche von Jamaicat
mit den Ausmaßen 640 Pixel x 480 Pixel. Die gesamte Spielfläche hat eine Größe von
960 Pixeln x 704 Pixeln. Die horizontalen Koordinaten beginnen links mit Null und die
vertikalen oben mit Null.
Der Spieler lenkt die schwarze Katze Jamaicat und muss die 9 Flaggen einsammeln.
Gehindert wird man daran von den blauen Gegnern. Wenn Jamaicat von diesen berührt
wird, verliert man eines der drei Leben, welche am oberen Bildschirmrand mit rotem Hintergrund zu sehen sind.
Aufgrund der Größe des Spielfeldes wird gescrollt, sobald Jamaicat sich dem Bildschirmrand nähert.
Das Spiel hat 5 Level, wobei sich im ersten Level zwei Gegner aufhalten. Hat man alle
Flaggen eingesammelt, kommt man in das zweite Level und die Gegnerzahl erhöht sich auf
drei. Außerdem werden die Flaggen erneuert. Dies wiederholt sich bis zum fünften Level.
Sind dort alle Flaggen eingesammelt, ist das Spiel durchgespielt.
Weiterhin gibt es zwei Schwierigkeitsmodi : “leicht” und “schwer”. Im Modus “leicht” sind
die Gegner langsam, im Modus “schwer” sind sie schnell.
1
2
GLBasic
GLBasic ist eine Programmiersprache, die von einem kleinen Entwicklerteam (Dream
Design) entworfen wurde. Im Internet gibt es hierzu Informationen unter www.glbasic.com.
Ich möchte hier nur kurz die wichtigsten Merkmale erwähnen.
GLBasic ist eine leicht zu erlernende Programmiersprache mit basic-ähnlichen Befehlen.
Wie bei anderen Hochsprachen (zum Beispiel QBasic oder C) arbeitet GLBasic mit Gleitkommazahlen und dynamischen Feldern. Es gibt lokale und globale Variablen, Ein - und
Ausgabefunktionen, If - Else - Verzweigungen, For To Next - Schleifen und kopfgesteuerte While Wend Schleifen. Weiterhin gibt es die üblichen arithmetischen Ausdrücke, sowie
Vergleichs-Operatoren und logische Operatoren. Man kann Funktionen und Subprogramme
erstellen und auf ein gutes Sortiment von vordefinierten Funktionen zugreifen.
GLBasic ist außerdem eine 2D/3D-Grafikengine. (Da in diesem Artikel ein zweidimensionales Computerspiel programmiert wird, gehe ich nicht weiter auf die 3D-Funktionalität
ein.) 2D-Engine heißt, dass in GLBasic Funktionen enthalten sind, die Bitmap - Grafiken
laden können, und mit diesen umgehen können. Mit einfachen Befehlen (die auf entsprechenden Funktionen basieren) kann man die geladenen Grafiken am Bildschirm darstellen.
GLBasic liefert ein fertiges Paket zur Erstellung von Computerspielen, welches dem Spieleprogrammierer alle Freiheiten lässt.
Es steht eine komfortabel Windows Benutzeroberfläche zur Verfügung und der Quellcode
wird schnell zu einer echten Executable kompiliert.
3
Grundlegendes
Auf der Internetseite www.glbasic.com kann sich der Leser eine Demoversion von GLBasic herunterladen. Diese Demoversion hat nur minimale Einschränkungen gegenüber der
Vollversion, und die Umsetztung des Computerspiels ist damit ohne weiteres möglich.
GLBasic enthält eine sehr umfangreiche Hilfedatei mit Befehlsreferenz und verschiedenen
Tutorials.
In diesem Artikel gehe ich davon aus, dass der Leser (der das Computerspiel programmieren möchte) grundlegende Kenntnisse im Programmieren hat. Weiterhin setze ich Kenntnisse im Umgang mit der Benutzeroberfläche voraus. Vor der Umsetzung von Jamaicat
empfehle ich, sich mit GLBasic etwas vertraut zu machen. Es wäre zum Beispiel sinnvoll sich die ersten Tutorials durchzulesen und die Benutzeroberfläche anzuschauen. Wenn
während der Programmierung Fragen auftauchen, bietet die Befehlsreferenz Hilfe. Eine
weitere Unterstützung findet man im GLBasic - Forum, welches unter www.glbasic.com
unter Support zu finden ist. Hier kann man sich mit anderen GLBasic - Programmierern
austauschen. Ich bin unter der E-Mail-Adresse [email protected] zu erreichen.
4
Aufbau des Artikels
Ich benutze Screenshots der GLBasic - Benutzeroberfläche, um den Quellcode in diesem
Artikel darzustellen. Die Screenshots sind als Abbildungen durchnummeriert, um zu ver2
deutlichen, welcher Programmabschnitt gerade besprochen wird. Ich gehe das Programm
von vorne bis hinten durch, so dass der Quellcode aus den Screenshots (in richtiger Reihenfolge abgetippt) das fertige Programm ergibt. Der Vorteil der Screenshots ist, dass Tippfehler vermieden werden. Dadurch, dass das Programm fehlerfrei kompiliert wird, enthalten
die Screenshots keine Fehler.
5
Start
Wenn GLBasic gestartet wird, bietet der Projektassistent an, ein neues Projekt zu erstellen, was auch erfolgt. Der Name des neuen Projektes soll Jamaicat sein. In der Menüleiste
muss über Projekt → Optionen auf Vollbild und 640x480 Pixel gestellt werden. Falls eine Internetverbindung besteht, sollte als erstes ein Update durchgeführt werden (in der
Menüleiste unter Web auf Internet Update klicken). Falls beim Kompilieren der Fehler
“gcc.exe: gpc temp.cpp: No such file or directory” auftritt, muss mit der rechten Maustaste auf den Quellcode geklickt und die Option “Datei ins Projekt übernehmen” gewählt
werden. Danach kann rechts im Übersichtsfenster unter der Karteikarte “Dateien” geprüft
werden, ob das Hauptprogramm nun “Jamaicat.gbas” ist.
Abbildung 2: Alle Grafiken für Jamaicat
Die Datei “Jamaicat.zip” enthält die Grafiken, die für das Spiel benötigt werden. Diese
Grafiken müssen in den Ordner “...\GLBasic\Projects\Jamaicat” eingefügt werden, der
auch die von GLBasic erzeugten Dateien “Jamaicat.gbap” und “Jamaicat.gbas” enthält.
In Abb. 2 sind alle benötigten Grafiken zu sehen. Falls die Datei “Jamaicat.zip” nicht
vorhanden ist, können die Grafiken aus Abb. 2 einfach nachgzeichnet werden. Alle Informationen zu Name, Größe und Farbtiefe sind in Abb. 2 enthalten.
3
Die Grafiken haben teilweise einen rosa Hintergrund. Der Grund dafür ist, dass genau
dieses Rosa für GLBasic durchsichtig ist. Dadurch werden die Spielfiguren mit Konturen
angezeigt und nicht als Rechtecke oder Quadrate.
Die Datei “Jamaicat.zip”, enthält auch die Musik und alle Sounds für Jamaicat. Diese
müssen sich ebenfalls im Ordner Jamaicat befinden, um abgespielt zu werden. Die Sounds
sind nicht unbedingt notwendig, und der Quellcode wird auch bei fehlenden Sounds kompiliert.
Die Datei “Jamaicat.zip” enthält außerdem den kompletten Quellcode und die ausführbare Datei “Jamaicat das fertige Spiel.exe”. Man kann das fertige Ergebnis also schonmal
anschauen und spielen.
6
Erstellung des Quellcodes
Im Folgenden wird der komplette Quellcode für das Computerspiel erzeugt. Jeder Abschnitt
wird genau beschrieben, und zusammengefügt ergeben die nummerierten Screenshots das
fertige Spiel. Der Quellcode wird im Text kursiv dargestellt.
6.1
Initialisierung
Zu Beginn des Programms werden alle notwendigen Initialisierungen durchgeführt. Der Co-
Abbildung 3: Initialisierung
de beginnt in Abb. 3 mit der Sprungmarke neustart:. Hierher wird gesprungen, wenn das
4
Spiel zuende ist. Entweder man ist dreimal gefangen worden, oder man hat das Spiel durchgespielt. Danach werden zwei Zeichensätze mit LOADFONT geladen. Diese Zeichensätze
kann man mit dem Zeichensatz Creator, der in der Menüleiste unter Werkzeuge zu finden
ist, erstellen. In der Datei “Jamaicat.zip” sind die Zeichensätze enthalten. Für alle denen
diese nicht zur Verfügung stehen, ist font.bmp ein Times New Roman Zeichensatz in der
größten Größe und kleinfont.bmp ein Times New Roman Zeichensatz in der halben Größe.
Beide haben die Farbe Gelb und die Option Cleartype (WinXP). Jede andere Farbe oder
Option funktioniert genauso gut.
Dann werden die Grafiken und die Sounds geladen (die Sounds müssen nicht zwingend
vorhanden sein).
Weiterhin werden 7 Variablen als global deklariert :
• geschwindigkeit=1 : Diese Variable bestimmt die Geschwindigkeit der Gegner. Eins
für langsam, zwei für schnell.
• anzahlleben=3 : Jamaicat hat drei Leben.
• levelz=0 : In jedem Level wird diese Variable um Eins erhöht und zeigt damit an in
welchem Level man sich befindet.
• gegner2aktiv=-1 : Pro Level wird gegner2aktiv um Eins erhöht. Ist dieser Wert größer
gleich 1 dann ist der “Gegner2” (wird später erklärt) aktiv im Spiel tätig. In Level
1 beträgt gegner2aktiv=0, in Level 2 dann gegner2aktiv=1, wodurch der “Gegner2”
dann aktiv wird.
• anzahlgegner3=-3 : Diese Variable gibt die Anzahl der Gegner vom Typ 3 (wird
später erklärt) wieder. Solange der Wert unter Null ist, ist kein Gegner vom Typ 3 im
Spielfeld. Der Wert der Variablen wächst bis 2, was bedeutet, dass dann insgesamt
3 Gegner vom Typ 3 aktiv sind (Es sind 3 Gegner aktiv, obwohl der Wert nur 2
beträgt, weil die Null mitgezählt wird).
• levelgeschafft=1 : Immer wenn ein Level erfolgreich beendet wurde, nimmt diese
Variable den Wert Eins an, damit der nächste Level initialisiert wird. Sie muss auch
zu Beginn des Spiels Eins sein, um in den ersten Level zu kommen.
• musik=1 : Wenn diese Variable Eins ist, dann spielt während des Spiels die Musik.
Ist sie Null, wird keine Musik gespielt.
Eine übliche Technik bei der Computerspieleprogrammierung ist es, das Spielfeld als eine Art Schachbrettmuster aufzubauen. Das bedeutet, dass das Spielfeld aus einer bestimmten Zahl an sogenannten “Kacheln” besteht. In Abb. 2 sieht man die Grafiken land.bmp
und himmel.bmp. Diese Grafiken sind 32 Pixel x 32 Pixel groß. Mit ihnen wird das komplette Spielfeld wie mit Kacheln ausgelegt. 30 Kacheln in horizontaler Richtung ergibt
30 Kacheln · 32 Pixel pro Kachel = 960 Pixel. Das Spielfeld ist also 960 Pixel breit. In vertikaler Richtung werden 22 Kacheln verlegt (22 Kacheln·32 Pixel pro Kachel = 704 Pixel).
Das Spielfeld ist 704 Pixel hoch. Die Spielfigur Jamaicat, die Gegner und die Flaggen sind
5
Abbildung 4: Initialisierung
alle 32 Pixel x 32 Pixel groß (genauso wie die Kacheln land.bmp und himmel.bmp, was bei
der Programmierung sehr nützlich ist).
In Abb. 4 wird das Array feld[22][30] initialisiert. In Tabelle 1 (auf der nächsten Seite)
ist das Array mit seinen Einträgen dargestellt. Betragen die Werte des Arrays gleich Null,
dann wird dort später eine Himmel - Grafik gemalt. Die Land - Grafik wird für die Werte
Eins gesetzt. Das heißt für i < 4 also für i von 0 bis 3 wird Himmel gemalt. Das entspricht
4 Kacheln in vertikaler Richtung (4 · 32 = 128). Der Himmel wird in horizontaler Richtung
128 Pixel hoch sein. Der Rest des Spielfeldes wird mit Land bedeckt.
Damit das Spielfeld nicht so kahl grün aussieht (und vor allem um zu sehen, dass sich die
Spielfiguren auch bewegen), werden (wie in Abb. 1 zu sehen) braune Punkte auf der grünen
Fläche verteilt. In Abb. 4 werden die Arrays braunepixelx[631] und braunepixely[631] dimensioniert. Diese bekommen in der FOR TO NEXT - Schleife zufällige Zahlen von 0 bis
32 zugeordnet und sind später die Koordinaten für die braunen Punkte im Spielfeld. Dann
bekommt das Array feld[22][30] 9 Einträge. Zum Beispiel wird feld[6][1] gleich Zwei gesetzt
(man beachte, dass die Indizes des Feldes mit Null beginnen feld[0][0] ). Das bedeutet, dass
an diesen Koordinaten eine Flagge positioniert wird. Die Flagge hat damit die vertikale
Position 6 · 32 = 192 und die horizontale Position 1 · 32 = 32 (die Koordinaten der Grafiken
beziehen sich immer auf die linke obere Ecke). Auf diese Weise werden die 9 Flaggen auf
dem Spielfeld verteilt.
6
0
0
0
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
0
1
1
2
1
1
1
1
1
1
2
1
1
1
1
1
1
2
1
0
0
0
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
0
1
1
2
1
1
1
1
1
1
2
1
1
1
1
1
1
2
1
0
0
0
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
0
1
1
2
1
1
1
1
1
1
2
1
1
1
1
1
1
2
1
0
0
0
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
Tabelle 1: Array feld[22][30]
Abbildung 5: Initialisierung
Jetzt kann in das erste Subprogramm mit GOSUB intro gesprungen werden. Dafür
muss zunächst die Sub intro erstellt werden. Eine neue Sub erstellt man über die Menüleiste unter Projekt und dann Neue Sub, bzw. über das entsprechende Button in der Symbolleiste. Die Abbildung 6 zeigt die Sub intro. Alle Befehle laufen innerhalb der intromarke:
- GOTO intromarke - Schleife ab. Die Befehle SETFONT, PRINT, ZOOMSPRITE und
ROTOZOOMSPRITE sollten klar sein, ansonsten kann in der Hilfedatei in der Befehlsreferenz noch einmal nachgeschaut werden. Durch den Befehl SHOWSCREEN werden alle
vorangegangenen Ausgabefunktionen durchgeführt.
Die Sub intro zeigt das Bild in Abb. 7 an. Es handelt sich um den Startbildschirm. Hier
kann der Spieler entscheiden, ob er 1 für leicht oder 2 für schwer wählt. Außerdem wird
darüber informiert, dass mit einem Druck auf die Taste M die Musik an- und ausgestellt
werden kann (geht nur während des Spiels).
Ansonsten enthält die Sub noch Zwei Key() - Befehle. Wird zum Beispiel über die Tastatur
die 1 gedrückt, wird die Variable geschwindigkeit gleich 1 gesetzt und es wird mit Return
aus der Sub herausgesprungen. Wird die Zwei auf der Tastatur gewählt, ist der Modus
“schwer” aktiv, und der Variablen geschwindigkeit wird der Wert 2 zugeordnet.
7
Abbildung 6: Sub intro
Abbildung 7: Startbildschirm
8
Abbildung 8: Initialisierung
Es geht weiter mit Abbildung 8. Begonnen wird mit der Srungmarke start:. Hierher
wird gesprungen, wenn Jamaicat im Spiel von einem Gegner gefangen oder das Level
erfolgreich geschafft wurde. Auf diese Weise wird nicht in die Sub intro gegangen, und es
werden auch die Variablen aus Abb. 3 nicht neu initialisiert.
Falls das letzte Level erfolgreich gemeistert wurde, steht die Variable levelgeschafft auf Eins,
und es wird in die Sub nextlevel gesprungen (genauso wie zu Beginn des Programms), weil
levelgeschafft mit dem Wert Eins initialisiert wurde. Deshalb wird an dieser Stelle die Sub
nextlevel erstellt (siehe Abb. 9).
Zu Beginn der Sub nextlevel werden die entsprechenden Felder des Spielfeldes, auf denen sich eine Flagge befindet, neu initialisiert, weil im vorangegangenen Level alle Flaggen
eingesammelt wurden. Dann wird levelgeschafft gleich Null gesetzt, damit im nächsten Programmdurchlauf nicht wieder in die Sub nextlevel gesprungen wird. levelz, gegner2aktiv,
anzahlgegner3 werden um Eins erhöht. Danach kommt noch eine Absicherung, damit anzahlgegner3 nicht größer als 2 wird. Darauf folgend wird levelz abgefragt. Ist die Variable
größer gleich 6, dann wurde der fünfte Level geschafft, und das Spiel ist zuende, weshalb
dann aus der Sub herausgesprungen wird. Jetzt beginnt eine Schleife, die PRINT - Befehle enthält, die wiederum mit SHOWSCREEN angezeigt werden. Außerdem enthält die
Schleife noch eine KEY - Abfrage. Es wird geprüft, ob die Leertaste (KEY(57)) gedrückt
ist. Ist dies der Fall, dann wird die Variable schalter gleich Eins gesetzt. Ist die Variable
schalter gleich Eins und die Leertaste nicht gedrückt, ist die nächste Bedingung erfüllt.
9
Abbildung 9: Sub nextlevel
10
schalter wird wieder Null gesetzt, und es wird aus der Sub herausgesprungen, damit das
Spiel weitergeht. Diese Eingaberoutine funktioniert also so, dass der Spieler am Bildschirm
aufgefordert wird, die Leertaste zu drücken, um fortzufahren. Aber erst wenn die Leertaste
losgelassen wird, wird aus der Sub gesprungen. Solche “Schalter” können bei der Programmierung von Computerspielen sehr nützlich sein.
Damit ist die Sub nextlevel erledigt.
In Abb. 8 geht es weiter mit einer Abfrage von levelz. Falls levelz größer gleich 6 ist,
ist das Programm schon aus der Sub nextlevel gesprungen. Das Spiel ist durchgespielt und
die Bedingung ist damit erfüllt. Es wird in die Sub gewonnen gesprungen, die in Abb. 10
zu sehen ist.
Abbildung 10: Sub gewonnen
In der Sub gewonnen wird Text angezeigt, und sie enthält die gleiche Tastaturabfrage
wie die Sub nextlevel. Nach Verlassen der Sub gewonnen, wird mit GOTO neustart zur
entsprechenden Marke gesprungen, und das Spiel beginnt von neuem.
In Abbildung 8 werden nun weitere Variablen als global deklariert.
• xpos=300 : xpos ist die horizontale Koordinate der Position von Jamaicat.
• ypos=140 : ypos ist die vertikale Koordinate der Position von Jamaicat.
• scrollx=-160 : Diese Variable ist für das horizontale Scrolling zuständig.
• scrolly=-112 : Diese Variable ist für das vertikale Scrolling zuständig.
11
• flaggea=0 - flaggei=0 : Diese Variablen werden Eins gesetzt, wenn Jamaicat eine
der neun Flaggen berührt, und sind sonst Null.
• gegner2x=100 und gegner2y=160 : gegner2x und gegner2y sind die Koordinaten vom
Gegner2.
• gegner2startschalter=0 : Diese Variable taucht in der Sub gegner2 auf und wird dort
erklärt.
• gegner1coll=0, gegner2coll=0, gegner3coll=0 : Wenn Jamaicat einen Gegner berührt,
bekommt die entsprechende Variable gegner1coll, gegner2coll oder gegner3coll den
Wert Eins zugeteilt, und ist sonst Null.
• geschnappt=0 : Wenn eine der Variablen gegner1coll, gegner2coll, gegner3coll gleich
Eins ist, wird der Wert von geschnappt gleich Eins.
Es geht weiter mit der Initialisierung :
Abbildung 11: Initialisierung
Es werden in Abb. 11 zwei Arrays dimensioniert, welche die Koordinaten der Positionen
der 3 Gegner vom Typ 3 beinhalten. Zum Beispiel ist die Position des ersten Gegners vom
Typ 3 horizontal gleich gegner3x[0]=64, die vertikale Positionen ist gegner3y[0]=352. Später
werden die verschiedenen Gegner noch genau betrachtet.
Damit ist die Initialisierung abgeschlossen.
12
6.2
Hauptschleife
Die Hauptschleife mit marke: - GOTO marke beinhaltet das eigentliche Spiel und wird
während des Spiels ständig durchlaufen.
Abbildung 12: Hauptschleife
Sie beginnt mit dem Befehl GOSUB music. Im nächsten Schritt wird die Sub music
erstellt (siehe Abb. 13). Da die Musik für das Spiel nicht unbedingt notwendig ist, möchte
ich nicht ausführlich auf die Sub music eingehen. Ergebnis der Sub ist, dass mit nur einer
Taste (M) die Musik während des Spiels an - und ausgestellt werden kann. Ein etwas
einfacherer Weg wäre, zwei Tasten zu benutzen. Man könnte das auf die folgende Weise
lösen :
IF KEY(50)=1 OR musik=1
PLAYSOUND 2,0,1
musik=1
ENDIF
IF KEY(49)=1
HUSH
musik=0
ENDIF
Falls die Taste M gedrückt ist, wird die Musik abgespielt und die Variable musik gleich
Eins gesetzt. Wird die Taste N gedrückt, bewirkt der Befehl HUSH das die Musik ausgestellt wird. Die Variable musik bekommt den Wert Null zugeordnet. Jetzt wird keine
Musik mehr abgespielt, weil musik dafür Eins sein muss.
13
Abbildung 13: Sub music
Als nächstes wird in die Sub level gesprungen. Abbildung 14 zeigt die Sub level. Hier
wird das Spielfeld gemalt. Als erstes wird eine Schleife durchlaufen, die das gesamte
feld[22][30] auf seine Einträge prüft. Wie schon erwähnt, wird für den Feldeintrag Null
eine Himmel - Grafik gesetzt, für die Eins eine Land - Grafik und für die Zwei eine Flagge.
Weiterhin werden die braunen Pixel auf dem Land verteilt. Dazu wird erst ab i>=4 (also
ab dem Ende vom Himmel) in die SETPIXEL - Funktion gegangen. Außerdem wird überprüft ob sich auf dem Feld auch keine Flagge mit Eintrag 2 befindet, damit die braunen
Pixel nicht auf die Flaggen gesetzt werden. Die Einträge der Pixelkoordinaten in braunepixelx[631] und braunepixely[631] sind Zufallszahlen zwischen 0 und 32. Diese werden zu
j*32 und i*32 addiert; dadurch wird in jede Landkachel ein brauner Pixel zufällig gemalt.
Nach dem Durchlaufen der Schleife werden noch die Berge und die Sonne gezeichnet.
Alle horizontalen Koordinaten werden mit der Variablen scrollx und alle vertikalen Koordinaten mit scrolly addiert. Diese Variablen sind für das Scrolling zuständig, was später
erklärt wird.
14
Abbildung 14: Sub level
In der Hauptschleife Abb. 12 wird als nächstes die Sub jamaicat aufgerufen. In diesem
Unterprogramm wird der Held des Spiels Jamaicat bewegt und gemalt. Außerdem wird
das Scrolling realisiert.
Abbildung 15: Sub jamaicat
In Abb. 15 beginnt die Sub jamaicat. Der KEY(200) ist die Pfeiltaste auf der Tastatur
nach oben, der KEY(208) der Pfeil nach unten, KEY(203) steht für Pfeil nach links, und
KEY(205) ist der Pfeil nach rechts.
Die erste IF ENDIF - Anweisung ist erfüllt, wenn keine Pfeiltaste gedrückt ist. Daraufhin
wird überprüft, ob die Variable blick gleich Null ist. Alle Variablen, die bei der Initialisierung nicht explizit deklariert werden, sind Null, solange man sie nicht verändert. Damit
ist diese Bedingung auch erfüllt. Jamaicat wird mit Blickrichtung nach rechts gemalt,
weil das Sprite Null die Grafik katze rechts.bmp darstellt. Wäre blick ungleich Null, würde
Sprite Eins, also Jamaicat mit Blickrichtung nach links, gemalt.
15
Abbildung 16: Sub jamaicat
16
Abbildung 17: Sub jamaicat
Weiter geht es in Abb. 16 mit der Sub jamaicat. Die folgende Abfrage dient dazu,
Jamaicat vertikal nach oben laufen zu lassen. Es wird geprüft, ob der Pfeil nach oben
gedrückt und der Pfeil nach unten nicht gedrückt ist. Ist die Bedingung wahr, wird die
vertikale Koordinate ypos von Jamaicat um 3 Pixel erniedrigt. Weiter wird geprüft, ob
weder die Pfeiltaste nach rechts noch die nach links gedrückt ist. Wäre dies der Fall, würde
Jamaicat nicht gemalt, denn die diagonale Bewegung wird weiter unten realisiert. Ist die
Bedingung erfüllt, wird noch überprüft, ob die Blickrichtung Null für rechts oder ungleich
Null für links ist, und das entsprechende Bild von Jamaicat gemalt. Die kommende Abfrage bewirkt, dass Jamaicat nach unten läuft, und funktioniert analog zur vorigen.
Als nächstes kommt die Abfrage, ob der Pfeil nach rechts oder links gedrückt ist, worauf die
Blickrichtung blick festgelegt wird. Werden zwei Pfeiltasten für eine diagonale Bewegung
gedrückt, wird weiter oben die vertikale Koordinate ypos verändert, aber kein Bild gemalt,
und in der rechts - links - Abfrage wird die horizontale Koordinate xpos verändert, worauf
dann das neue diagonal verschobene Bild gemalt wird. Durch die Abfrage IF KEY(200)=1
AND KEY(208)=1 ist abgesichert, dass es zu keiner Bewegung kommt, wenn die Pfeiltasten nach oben und nach unten gleichzeitig gedrückt werden. ypos wird nicht verändert.
Danach bewirkt die Abfrage IF KEY(203)=1 AND KEY(205)=1, dass es zu keiner Bewegung kommt, wenn die Pfeile nach rechts und links gleichzeitig gedrückt werden. Im
folgenden Teil der Sub wird das Scrolling umgesetzt. Es geht weiter mit der Abfrage IF
xpos>408 AND scrollx> −320.
Wenn die horizontale Koordinate den Wert 408 hat, befindet sich Jamaicat (Größe 32
17
Pixel) genau 200 Pixel vom rechten Rand entfernt.
408 + 32 + 200 = 640
(1)
scrollx wurde in Abb. 11 mit dem Wert -160 initialisiert. Dieser Wert ist größer als 320, und sobald xpos die 408 übersteigt, ist die Bedingung erfüllt. xpos wird auf dem
Wert 408 festgehalten, was bedeutet, dass Jamaicat auf der Stelle verharrt, obwohl die
Pfeiltaste nach rechts gedrückt ist. scrollx wird um 3 Pixel erniedrigt, was dazu führt,
dass in der Sub level in Abb. 14 alle Grafiken, die dort gemalt werden, um 3 Pixel nach
links verschoben werden, da bei allen Sprite - Befehlen ein scrollx in der horizontalen
Positionierung auftaucht. Der Effekt ist das Scrolling. Jamaicat bleibt am Bildschirm auf
seiner Position, aber der gesamte Hintergrund verschiebt sich nach links, wodurch eine
Bewegung nach rechts realisiert wird. Wenn sich der Hintergrund um 320 Pixel nach links
geschoben hat, ist das Ende des Spielfeldes erreicht. Jetzt darf nicht mehr gescrollt werden.
Weiter unten ist scrollx begrenzt, so dass der Wert nicht unter -320 sinkt. Hat der Wert die
-320 erreicht, wird IF xpos>408 AND scrollx> −320 nicht mehr erfüllt. xpos kann wieder
anwachsen und scrollx ist eingefroren. xpos darf aber nicht größer gleich 608 werden, damit
Jamaicat nicht aus dem Bild läuft. Deshalb wird die Koordinate xpos, sobald sie größer
gleich 608 ist, bei 608 festgehalten. Dann erfolgt eine Scrolling - Routine in die andere
horizontale Richtung, die analog zu der gerade beschriebenen Situation funktioniert, außer
dass der Hintergrund nach rechts verschoben wird.
Nun wird das Scrolling in vertikaler Richtung durchgeführt. Wenn die Abfrage IF ypos>248
AND scrolly> −224 wahr ist, wird Jamaicat bei ypos gleich 248 festgehalten, was genau
der Entfernung von 200 Pixeln vom unteren Bildschirmrand aus entspricht.
248 + 32 + 200 = 480
(2)
scrolly wird um 3 Pixel erniedrigt, wodurch der Hintergrund in der Sub level nach oben
geschoben wird. scrolly wird nicht kleiner als -224, weil dann das Ende des Spielfeldes
erreicht ist.
ypos + Größe Jamaicat − scrolly + Abstand = Ende Spielfeld
248 + 32 − (−224) + 200 = 704
(3)
(4)
Sobald scrolly kleiner gleich -224 ist, wird die Variable bei -224 eingefroren. ypos kann
dann bis 448 anwachsen, d.h. Jamaicat kann bis zum unteren Bildschirmrand laufen. Das
Scrolling nach oben ist etwas einfacher. Jamaicat darf nicht über die Berge in den Himmel
laufen. Deshalb darf scrolly nicht kleiner als 152 werden. Ist scrolly kleiner als 152, wird
außerdem gescrollt, aber nur solange scrolly kleiner gleich Null bleibt. Dann ist der obere
Rand des Spielfeldes zu sehen.
Als nächstes kommt die Sub einsammeln. Hier findet die Kollisionsabfrage zwischen
Jamaicat und den Flaggen statt.
18
Abbildung 18: Sub einsammeln
19
Es wird in Abb. 18 mit 9 Kollisionsabfragen begonnen. Je Flagge eine Abfrage. Man
beachte, dass die Koordinaten der Flaggen die Variablen scrollx und scrolly enthalten, da
sie in der Sub level mit dem Hintergrund verschoben werden. Wenn eine der Kollisionsvariablen Eins ist, und das zur Flagge entsprechende Feld gleich 2, dann wird das Feld
gleich Eins gesetzt, wodurch die Flagge verschwindet und durch eine Land - Grafik ersetzt
wird. Ferner wird ein Sound abgespielt. Nochmal wird dann nicht in diese IF - Abfrage
gegangen, weil das Feld nun nicht mehr den Wert 2 hat. Diese Prozedur wird für alle 9
Flaggen durchgeführt. levelgeschafft wird dann gleich Eins gesetzt. Es folgt eine Schleife,
die das gesamte von Land bedeckte Spielfeld durchgeht, und es wird geprüft, ob sich noch
Flaggen (mit Feldeinträgen 2) im Feld befinden. Wenn ja, wird levelgeschafft gleich Null
gesetzt; wenn nicht, bleibt levelgeschafft gleich Eins, und in der Hauptschleife wird dafür
gesorgt, dass das nächste Level vorbereitet wird.
Nun geht es in die Sub gegner1, in der die Steuerung des ersten Gegners durchgeführt
wird (genauer gesagt gibt es zwei Gegner vom Typ 1).
Abbildung 19: Sub gegner1
Es läuft eine Schleife von Null bis Eins, das sind zwei Durchläufe. Das erste mal wird die
Grafik des blauen Gegners in vertikaler Richtung auf 300 gesetzt, weil 300 + 224 · 0 = 300
ist, solange i = 0. Beim zweiten Durchgang wird eine Grafik in vertikaler Richtung auf
300 + 224 · 1 = 524 gesetzt. Damit befinden sich zwei Gegner vom Typ 1 im Spielfeld. Es
werden wieder die Scrollvariablen zu den Koordinaten addiert, weil auch die Gegner mitscrollen müssen. Dann kommt eine Kollisionsabfrage zwischen Jamaicat und den Gegnern,
wobei hier nicht die genauen Positionen abgefragt werden. Die Position von Jamaicat wird
horizontal und vertikal um 12 Pixel verschoben angegeben. Die Größe von Jamaicat wird
anstatt mit 32 Pixeln mit 8 Pixeln ausgewiesen. Dadurch kommt es nur zu einer Kollision,
wenn das innere 8 Pixel x 8 Pixel - Quadrat von der Jamaicat - Grafik auf die Grafik
20
des Gegners trifft. Dadurch hat der Spieler etwas mehr Raum und wird nicht so leicht
gefangen. Ist die Kollisionsvariable gleich Eins, ertönt ein Sound, und es wird in die Sub
gefangen gesprungen, die jetzt vorgestellt wird.
Abbildung 20: Sub gefangen
geschnappt wird Eins gesetzt und anzahlleben wird um Eins verringert. Es erscheint ein
Bilschirm mit Text, und die bekannte Leertastenschalter - Routine aus Abb. 10 ist in der
Sub enthalten.
Dadurch, dass geschnappt gleich Eins ist, wird in der Hauptschleife Abb. 12 eine Bedingung
erfüllt und zu der Sprungmarke start: gewechselt. Es werden verschiedene Variablen neu
deklariert, und nachdem die Hauptschleife wieder erreicht ist, beginnt das Level von vorne.
Die eingesammelten Flaggen werden nicht erneuert.
Zurück in der Sub gegner1 Abb. 19 wird eine IF - Abfrage durchgeführt, die prüft,
ob gegner1x kleiner gleich Null ist oder der gegner1schalter gleich Null ist. Trifft dies zu,
bleibt gegner1schalter gleich Null, und gegner1x wird um 4 erhöht. Erreicht der Gegner
das rechte Ende des Spielfeldes bei 928 (plus die Grafik mit 32 Pixeln ergibt 960), wird der
gegner1schalter gleich Eins und gegner1x solange erniedrigt, bis gegner1x wieder kleiner
gleich Null ist und der Kreislauf von neuem beginnt. Auf diese Weise laufen die beiden
Gegner von links nach rechts über den Bildschirm. Da die Schleife zweimal durchlaufen
wird, wird auch gegner1x zweimal erhöht oder erniedrigt, weshalb die Gegner im Endeffkt
eine Geschwindigkeit von 8 Pixeln pro Programmdurchlauf haben.
In der Hauptschleife Abb. 12 folgt eine IF - Abfrage, ob gegner2aktiv größer gleich
21
Eins ist. Dies ist der Fall, wenn die Sub level Abb. 14 zweimal durchlaufen wurde, und
Jamaicat sich im zweiten Level befindet. Die Sub gegner2 wird erstellt.
Abbildung 21: Sub gegner2
Die Grafik des blauen Gegners wird mit den anfangs initialisierten Koordinaten gegner2x und gegner2y sowie den Scrollvariablen gezeichnet. Darauf folgt eine Kollisionsabfrage mit Jamaicat (wie aus der Sub gegner1 bekannt ist). Falls es zur Kollision kommt,
ertönt ein Sound, und es wird (wie bei der Sub gegner1 ) in die Sub gefangen gesprungen.
gegner2startschalter ist eine Variable, die zur Verzögerung der Aktivität vom Gegner 2
zuständig ist. Erst wenn diese Variable größer gleich 90 ist, wird der Gegner 2 aktiv und
fängt an, sich zu bewegen. Dadurch hat der Spieler die Möglichkeit, zu Beginn des Levels
kurz einen Überblick über die Situation zu gewinnen, bevor er vom Gegner 2 gejagt wird.
Im Folgenden wird überprüft, ob die Position des Gegners 2 von der Position Jamaicats
abweicht. Ist die horizontale Koordinate gegner2x plus scrollx des Gegners 2 größer gleich
xpos (die Position von Jamaicat), wird gegner2x um den Betrag von geschwindigkeit erniedrigt. Ist die horizontale Position von Gegner 2 kleiner als von Jamaicat, wird seine
Position vergrößert. In vertikaler Ausdehnung passiert das Gleiche. Dadurch verfolgt der
Gegner 2 Jamaicat.
22
Es folgt die Sub gegner vom typ3.
Abbildung 22: Sub gegner vom typ3
Es wird in die Sub gegner vom typ3 gesprungen. Die erste FOR TO NEXT - Schleife läuft von Null bis anzahlgegner3. D.h. im ersten Level ist anzahlgegner3 gleich -2, im
zweiten -1 und im dritten Level 0, so dass die Schleife dann zum ersten Mal einmal durchlaufen wird. Da die Schleife nur einmal durchlaufen wird, wird auch nur ein Gegner mit
der Position gegner3x[0] und gegner3y[0] gemalt. Es folgt die bekannte Kollisionsabfrage.
Im vierten und fünften Level wird anzahlgegner3 jeweils um Eins erhöht, und die anderen
Gegner werden in der Schleife gemalt.
Die zweite FOR TO NEXT - Schleife bewegt zwei der maximal drei Gegner vom Typ
3. Diese beiden mit den Indizes [0] und [1] sind horizontal jeweils am linken und rechten Bildschirmrand fest positioniert. Falls ihre Position größer gleich ypos, (der Position
von Jamaicat), ist, wird die entsprechende gegner3y[j] - Koordinate um den Betrag von
geschwindigkeit erniedrigt. Ist gegner3y[j] kleiner gleich ypos wird die Koordinate um geschwindigkeit erhöht. Der Effekt ist, dass die beiden Gegner Jamaicat vertikal verfolgen,
horizontal aber unbeweglich sind.
Zum Schluss wird der dritte Gegner mit dem Index 2 bewegt. Dieser Gegner hat eine feste
vertikale Position und verfolgt Jamaicat horizontal. Die Positionen der Gegner enthalten
wieder die Scrollvariablen, da sie mit dem Hintergrund mitscrollen müssen.
Jetzt wird die Sub leben erstellt. In Abb. 23 wird mit FILLRECT ein Rechteck gemalt,
worauf eine Schleife folgt, die von 1 bis anzahlleben läuft. anzahlleben ist mit dem Wert 3
23
Abbildung 23: Sub leben
initialisiert, d.h. die Schleife wird dreimal durchlaufen. Es wird also dreimal das Sprite Null
in halber Größe mit ZOOMSPRITE genau auf das Rechteck gezeichnet. Die drei Bilder
repräsentieren die Leben von Jamaicat. Wird Jamaicat von einem Gegner gefangen, wird
in der Sub gefangen die Variable anzahlleben um Eins verringert. In der Sub leben wird
dann ein Bild weniger gemalt.
Zurück in der Hauptschleife Abb. 12 wird geprüft, ob geschnappt gleich Eins ist. Wenn
ja, wird zur Sprungmarke start: gewechselt.
Als nächstes wird geprüft ob anzahlleben kleiner gleich Null ist. Trifft dies zu, wurde
Jamaicat dreimal gefangen. Das Spiel ist zuende. Es wird in die Sub verloren gesprungen.
Abbildung 24: Sub verloren
24
In der Sub verloren wird Text ausgegeben. Sie enthält die bekannte Leertastenschalter
- Routine.
Nachdem aus der Sub verloren herausgesprungen wurde, wird mit GOTO neustart das
Spiel von neuem begonnen. Es folgt eine Abfrage, ob levelgeschafft gleich Eins ist. Ist diese
Bedingung erfüllt, wird zur Marke start: gesprungen. Dadurch wird das nächste Level
initialisiert.
Das letzte Unterprogramm ist die Sub vogel. Hier wird der Vogel animiert. Diese Art
der Animation kann auch auf die anderen Spielfiguren übertragen werden. So könnte man
zum Beispiel mehrere Bilder von Jamaicat, mit unterschiedlichen Fußpositionen malen,
die eine Laufbewegung darstellen würden.
Abbildung 25: Sub vogel
In Abb. 25 wird die nicht initialisierte Variable vogelz um Eins erhöht welche damit
den Wert Eins annimmt. Es folgt eine SELECT CASE ENDSELECT - Fallunterscheidung
mit dem Argument vogelz. Solange vogelz kleiner gleich 8 ist, wird Sprite 8 angezeigt. Für
vogelz von 9 bis 16 wird Sprite 9 auf den gleichen Koordinaten wie Sprite 8 angezeigt.
D.h., in den ersten 8 Programmdurchläufen sieht der Spieler das Bild 8 vom Vogel, in den
darauffolgenden 8 Programmdurchläufen das Bild 9, dann das Bild 10 und 11. Bei dem
Bild 11 hat der Vogel die Flügel durchgeschlagen und muss sie jetzt wieder heben. Bild
10 wird wieder angezeigt darauf Bild 9. Jetzt ist der Kreislauf einmal durchgelaufen, und
die Animation beginnt von neuem, indem vogelz sobald der Wert größer gleich 48 ist Null
gesetzt wird.
25
Als letzter Befehl in der Hauptschleife zeigt ein SHOWSCREEN alle gesetzten Grafiken
an.
Das Spiel Jamaicat ist fertiggestellt.
26

Documents pareils