GLBasic Benutzerhandbuch

Main sections

01 Allgemein

Hi und willkommen zu GLBasic, Deiner neuen Programmiersprache.

Hier lernst Du innerhalb kürzester Zeit wie Du mit GLBasic Deine Programm-Idee selbst verwirklichen kannst. Ein Wort vorweg: GLBasic ist kein Zaubermittel. Es hat seine Stärken und auch seine Grenzen. GLBasic lächelt über Aufgaben wie Sprite-Rotationen, AlphaBlending und Zoomen. (Wenn Du nichts davon kennst, egal. Wird alles später erklärt.). Um stabile Geschwindigkeiten auf allen Rechnen zu erhalten, kann GLBasic wenn nötig auf eine einstellbare Anzahl von Bildern pro Sekunde gebremst werden.

Kapitel 1: Programmiergrundlagen.



Ein Programm kann grundsätzlich fast gar nichts. Und genau das ist das Schwierige daran. Programme können nur:
-Variablen deklarieren
-Sprünge zu anderen Programmteilen machen
-Rechenoperationen mit Variablen durchführen
-Variablen an Funktionen übergeben

Ein Kompiler verwendet diese Befehle und wandelt sie in eine Sprache um, die der Rechner versteht.

1.1 Grundlegendes zu GLBasic:


GLBasic ist eine Variante der BASIC Programmiersprache, wenn auch eine sehr einfache. Programmiersprachen haben ihre eigene Syntax (Grammatik). Solange Du sie 100% einhältst, versteht GLBasic Dich auch zu 100%!

GLBasic beendet jeden Programmbefehl mit einem ';' oder einer neuen Zeile.

Alle Befehle von GLBasic müssen IMMER GROSS geschrieben werden. Der Editor macht das von selbst, wenn er einen Befehl erkennt. Sollte das nicht der Fall sein, scheint der Befehl inkorrekt geschrieben.

Jedes Zeichen RECHTS von einem '//' oder dem Befehl 'REM' wird als Kommentar zum Quellcode (also dem Programm) aufgefasst und hat keine Wirkung auf das Programm selbst. Es macht es nur übersichtlicher.

GLBasic benutzt versteckte Bildschirmseiten für flackerfreien Grafikaufbau. Wenn Du irgendetwas mit GLBasic programmierst, siehst Du zunächst gar nichts! Erst wenn Du den Befehl 'SHOWSCREEN' aufrufst, wird Deine gerade bearbeitete Seite sichtbar, und Deine neue zu bearbeitende Seite wird gelöscht, bzw. mit dem geladenem Hintergrundbild versehen. Das ist jetzt etwas früh, trotzdem merken: Wenn Du nichts siehst, überlege ob Du 'SHOWSCREEN' vergessen hast.

1.2 Unser erstes Programm:



Starte den Editor und wähle im Assistenten "Neues Projekt". Gib als Namen "HelloWorld" ein und klick auf OK. Nun tippe folgendes Programm in den Editor, speichere alles (Menü: Datei/Alles Speichern) und Kompiliere (erstelle) dann das Programm mit dem Sandeimer-Knopf oder Menü: Compiler/Compilieren.
Nun starte es mit dem Joypad Knopf, oder wähle Menüpunkt Compiler/Run

////////////// 
// HELLO WORLD
//////////////
// Mein erstes Programm
PRINT "HELLO WORLD!" ,100,100
SHOWSCREEN
MOUSEWAIT
END


Du solltest nun einen schwarzen Bildschirm mit der Aufschrift 'HELLO WORLD!' sehen.
Wenn Du auf die Maus drückst, ist das Programm beendet. Damit hast Du den ersten Schritt in Deine neue Welt getan.

Genug, fangen wir mit dem Leichtesten an: Variablen deklarieren.

Bei GLBasic gibt es 3 Variablen-Typen: Zahlen, Ganzzahlen und Wörter.
Variablen stellen wir uns als Schubladen vor. Auf der Schublade steht der Name der Variable, also der Variablenname und in der Schublade finden wir dann den Inhalt der Variablen, den Variablenwert. Beginnen wir mit Zahlen und sehen dann, was wir damit so alles anstellen können.

1.3 ZAHLEN


LET a=5


Wir rufen den Befehl 'LET' auf, und sagen wir hätten gerne eine Variable mit dem Namen 'a' die den Wert 5 beinhalten soll. Beende den Befehl mit ';' und haben unsere erste Zeile Programm geschrieben.

Damit das Ganze etwas schneller geht, bietet GLBasic auch die Möglichkeit, das 'LET' wegzulassen. Die Zeile sähe dann so aus:
a=5

und
LET a=5
LET a=a+1

sähe dann so aus:
a=5
a=a+1

Was tun wir hier? Nun, wir sagen die Variable mit dem Namen 'a' hat den Wert 'a+1'. Da 'a' aber von vorher schon den Wert 5 hat, weisen wir der Variable 'a' in Wirklichkeit den Wert '5+1' zu, also 6.
Wir können auch andere Rechenoperationen durchführen. GLBasic kennt folgende Operatoren:
+, -, *, /; (Plus=Addition, Minus=Subtraktion, Mal=Multiplikation, Geteilt=Division)

ACHTUNG:

LET a= 3+4*5;

Wäre laut Adam Riese 3+(4*5)=23 (Punkt vor Strich). Das war bei älteren Versionen von GLBasic nicht so. GLBasic hat zum Berechnen von Termen folgende Hierarchie:
(Klammern zuerst) * / + - AND OR < > =

Es gibt bei GLBasic ein paar Sonderfunktionen, die anders arbeiten als der Rest.
SIN(), COS(), TAN(), RND(), KEY()
Diese Funktionen geben einen Wert zurück.

Der Befehl RND() gibt eine Zufallszahl zurück. (Random)
LET a=RND(50) // a= Zufallszahl von 0 bis einschl. 50 


Wenn man beim Erstellen einer Variablen (z.B. mittels LOCAL/GLOBAL Befehl, oder bei der ersten Verwendung ein '%' anhängt ist die Zahl eine Ganzzahl. Beim optionalen Anhängen von '#' ist die Zahl eine Gleitkommazahl. Die Anhängsel sind bei der weiteren Verwendung der Variablen optional.

<B>Hinweis:</B>
GLBasic arbeitet standardmäßig mit Gleitkommazahlen. Das heißt, bei Divisionen muss die Funktion INTEGER() verwendet werden, wenn man eine Ganzzahlenoperation durchführen möchte.


1.4 WÖRTER (Zeichenketten)



Wörter unterscheiden sich in ihren Variablennamen durch ein angefügtes '$' von Zahlen. Zahlen lassen sich einfach in Zeichenketten umwandeln. Mehr dazu später in einem Beispiel.
LET a$="HALLO"

Wie oben geben wir der Variablen mit dem Namen 'a$' den Wert "HALLO". Wörter die statisch, also fest im Programm verankert sind (Konstanten), müssen immer durch " " abgetrennt werden, um sie von Variablen unterscheiden zu können.
Der Befehl 'LET' ermöglicht ein paar feine Funktionen mit Wörtern.
LET a$="MEINE"
LET b$="LIEBLINGSZAHL"
LET c= 7
// Jetzt kommts!!
LET d$=a$ + " " + b$ + " : " + c
PRINT d$,0,20
SHOWSCREEN

Ausgabe:
MEINE LIEBLINGSZAHL : 7
Wir können also mit 'LET' Zahlen in Wörter umwandeln (d$=c) und Wörter, sowie statische Texte miteinander verknüpfen (+). Was für einen Sinn das hat? Wenn unser Programm Bild 5 laden soll, muss es den Dateinamen in einem Wort an die Funktion übergeben. Wir könnten also, wenn die Datei heisst: 'Level5.dat' ein Wort bilden indem wir schreiben:
LET bildnummer=5 // Das passiert natürlich irgendwo im Programm... 
LET level$="Level" + levelnummer + ".dat"

Dazu aber später in einem Beispiel mehr. Das 'LET' ist übrigens auch hier nur zur Übersichtlichkeit und kann auch einfach weggelassen werden.

Achtung: c und c$ sind zwei verschiedene Variablen. Bei Zahlen (c% = integer und c#=floating point) kann % oder # nach der Initialisierung weggelassen werden. Die Variable hat nur den Namen "c", das "%" oder "#" ist nur eine Zusatz-Information für den Compiler.

GLBasic bietet Dir noch ein paar besondere Funktionen an, um mit Wörtern umzugehen.
INPUT name$, x, y

Gibt an der Stelle x, y einen blinkenden Cursor aus, mit dem Du ein Wort eingeben kannst. Nach Abschluss mit der Return-Taste wird das eingegebene Wort in die Variable 'name$' eingesetzt. Das funktioniert auch mit Zahlen
(INPUT zahl, x,y;)
ziel$=MID$(quelle$, start, länge)

Dieser Befehl ermöglicht es, aus Wörtern 'Unterwörter' herauszuschneiden. Dabei wird aus der Variablen quelle$ ein Wort, beginnend mit dem Buchstaben Nr. 'start' und der Länge 'länge' in die Variable mid$ geschrieben. Der erste Buchstabe des Wortes quelle$ hat den Startindex '0'.

Beispiel:
name$="Mein Auto ist blau"
m$=MID$(name$, 5, 4)
PRINT m$ , 20, 20
SHOWSCREEN

Ausgabe:

Auto

Du kannst damit z.B. Namenseinträge in einer Highscoreliste auf 7 Buchstaben beschränken, indem Du einfach nur die ersten 7 Buchstaben herausschneidest.
INPUT eingabe$, 100, 100
name$ = MID$(eingabe$, 0, 7)


wort$ = FORMAT$(numbuchst, numnachkomma, zahl)

Damit kann man Zahlen "schöner" in Wörter umwandeln. Behalte das im Gedächtnis, falls Du es einmal brauchen solltest.

1.5 DATENFELDER



Du hast nun einen Überblick über Variablen bekommen. Wie würdest Du aber darin z.B. ein Spielfeld speichern? Richtig! Gar nicht. Dafür benutzt Du am besten Datenfelder.
Ein Datenfeld kann man sich vorstellen wie ein Schachbrett. Es hat 8 Felder nach rechts (x) und 8 Felder nach unten (y). Ein solches Feld definieren wir in GLBasic so:
DIM schachbrett[8][8]

Dadurch wird im Rechner der Speicherplatz vorbereitet, in dem unser Schachbrett gespeichert ist, und alle Felder werden auf 0 gesetzt.
Wollen wir jetzt auf das Feld 3 nach rechts und 4 nach unten den Wert 7 schreiben, so schreiben wir:
LET schachbrett[2][3]=7

Warum 2 und nicht 3?? Nun weil Datenfelder nun einmal bei 0 beginnen. 0,1,2,3,4,5,6 sind 7 Felder. Zugegeben, das mag etwas verwirren, ist aber nach kurzer Zeit vergessen und wird automatisch richtig gemacht.
Du kannst Datenfelder auch mit Variablen anspringen.
LET Schachbrett[2][6]=7
LET x=2
LET y=6
LET a=schachbrett[x][y]
PRINT "Schachbrett[2][6] hat den Wert:", 100, 80
PRINT a, 100, 100

Ausgabe:
Schachbrett[2][6] hat den Wert:
7

Weil Du ihn vorher in das Feld geschrieben hast.

ACHTUNG:

Datenfelder dürfen nicht mehr als 4 Dimensionen haben.
DIM a[1][2][3][4]; // Gerade noch OK 

Datenfelder können auch aus Wörtern und mit unterschiedlichen Dimensionen geschaffen werden.
Beispiele:
DIM raum[10][10][10] // Ein Zahlenraum mit x, y und z
// je 10 Feldern (0-9)
DIM name$[5] // 5 Wörter
LET name$[0]="Hugo"
LET name$[1]="Tim"
DIM kinobesucher$[30][10]
LET kinobesucher$[sitz][reihe]="Tom"

Mit dem Befehl REDIM kann man einem Feld eine neue Größe zuweisen und die bereits gespeichterten Datenelemente beibehalten.

Um ein Feld zu kopieren schreibt man:
DIM a[5]
b[] = a[]

Das erstellt ein neues Feld b[5] und kopiert die Daten von a[] hinein.

Um aus einem Feld eine Reihe herauszunehmen, kann man DIMDEL verwenden. Das ist sehr angenehm, da man dadurch einfach dynamische Anzahlen von Elementen handhaben kann. Mehr Information dazu gibt es in der Befehlsreferenz.

Der letzte Wert eines Feldes ist a[ LEN(a[])-1 ], oder einfach nur kurz a[ -1 ]. Der vorletzte ist a[ -2 ].

1.6 SPRUNGMARKEN:



Problem: Das Programm läuft einmal durch und ist dann aus.
Lösung: Wir lassen das Programm wieder zum Anfang springen.
Beispiel:
// Ein GOTO Beispiel 
anfang:
LET a=RND(600)
LET b=RND(400)
PRINT "TOLL",a ,b
SHOWSCREEN
MOUSEWAIT
GOTO anfang

Was tut das Programm? Es setzt eine Sprungmarke mit dem Namen 'anfang', sagt 'a' habe einen zufälligen Wert zwischen 0 und 600, b zwischen 0 und 400. Dann schreibt es an die Position a-Pixel nach rechts und b-Pixel nach unten das Wort "TOLL", zeigt das Ganze und wartet, bis die Maus gerückt wird.
Nun springt das Programm zu der Sprungmarke 'anfang' und wiederholt das Ganze. Um das Programm zu beenden, drückst Du auf die 'Esc' Taste. Das solltest Du Dir gut merken. Hängt Dein Programm, kannst Du es mit 'Esc' beenden.

Damit kann man schon ganz schön viel anfangen. Will man aber einen Teil eines Programms so schreiben, dass man ihn von verschiedenen Positionen aus anspringen kann, braucht man eine sog. Sub-Funktion. Dadurch lassen sich Programmteile mehrmals benutzen. Der Aufruf erfolgt jetzt über 'GOSUB', und das Programm fährt an der aktuellen Stelle wieder fort, sobald eine Sub-Funktion mit 'RETURN' oder 'ENDSUB' abgeschlossen wird.

SUBs definierst Du in GLBasic am einfachsten mit dem Menüpunkt "Projekt/Neue SUB"

Ein Beispiel:
// Ein GOSUB Beispiel 
PRINT "ANFANG",0,0
GOSUB mitte
PRINT "ENDE",0 ,30
END

SUB mitte:
PRINT "MITTENDRIN",0,20
RETURN // Das springt zurück, falls nötig
ENDSUB // Ende der Sub


Ausgabe:
ANFANG
MITTENDRIN
ENDE

Ein gutes Beispiel für eine Sub-Funktion ist zum Beispiel die Routine zum Laden von Feldern. Sie kann so im Programm als auch im Leveleditor aufgerufen werden.

ACHTUNG:

SUBs stehen immer am Ende des Hauptprogramms. Zwischen den Befehlen ENDSUB und SUB darf KEIN Befehl erfolgen ausser Kommentaren.
Du kannst nicht mit GOTO aus einer SUB ins Hauptprogramm springen, und nicht vom Hauptprogramm in eine SUB springen.

FOR-SCHLEIFEN:



Angenommen, wir wollen Datenfelder mit 1 befüllen. Wie lange würde das wohl zu Programmieren dauern, wenn das Feld 10 Zahlen groß ist?
Nicht lange:

FOR x=0 TO 9
LET feld[x]=1
NEXT


Das Programm zwischen FOR und NEXT wird so lange ausgeführt, bis x>9 ist. Bei jedem Aufruf von NEXT wird x um 1 erhöht. Kompliziert? Nochmal langsam:
FOR x=0 TO 9

Es sei die Variable x mit dem Wert 0 gefüllt. Das folgende Programm ist zu wiederholen, bis x größer als 9 ist.
LET feld[x]=1

Die Datenfeld 'feld' wird an der Stelle 'x' mit dem Wert 1 gefüllt.
NEXT

x wird um 1 erhöht. Das Programm zwischen FOR und NEXT wird wiederholt.

Nun füllen wir ein Feld der Größe 100x100 mit 1ern.
FOR x=0 TO 99
FOR y=0 TO 99
LET feld[x][y]=1
NEXT
NEXT


Das geht auch rückwärts oder in anderen Sprüngen. Mit
STEP

kannst Du angeben, um wieviel Dein Zähler erhöht/vermindert werden soll.

FOR x=24 TO 0 STEP -5
PRINT x, 0, (x*20)
NEXT


Die Befehle
BREAK
und
CONTINUE
ermöglichen ein Verlassen einer Schleife oder ein frühzeitiges Wiederholen der Schleife.

WHILE-SCHLEIFEN



Eine WHILE Schleife wird so lange ausgeführt, bis das Argument falsch wird. Wir wollen also beispielsweise eine Zufallszahl zwischen 3 und 10 haben. Nun lassen wir uns eine Zufallszahl zwischen 0 und 10 ausgeben, und wiederholen das Ganze bis die Zahl größer als 3 ist.

LET z=0     // z von vornherein < 3,
// sonst wird WHILE Schleife
// nicht ausgeführt!
WHILE z<3 // Solange z kleiner als 3,
z=RND(10) // ist z eine Zufallszahl von 0-10
WEND // Wiederholen.

Oder eine Zahl zwischen 0 und 10, aber nicht die 5!
LET z=5     // z gleich 5
// sonst wird WHILE Schleife
// nicht ausgeführt!
WHILE z=5 // Solange z gleich 5
z=RND(10) // ist z eine Zufallszahl von 0-10
WEND // Wiederholen.


Übrigens, Zufallszahlen zwischen 3 und 10 machst Du besser so:

z= RND(7)+3 // (0 bis 7) +3 = (3 bis 10) 

See also...