Easy Game Scripting mit Lua (EGSL)
Viele denken, es sei aufwändig, kleinere Spiele zu programmieren. Dabei kann es mit EGSL so einfach sein. Der Artikel zeigt auf, was es mit dem Interpreter auf sich hat und wie EGSL entstand. In einem ersten Beispiel wird gezeigt, wie man prinzipiell mit EGSL zweidimensionale Spiele programmieren kann.
Einführendes Beispiel
Ein einführendes Beispiel soll zeigen, wie man mit EGSL eine Grafik mittels der Pfeiltasten auf dem Bildschirm bewegen kann. Um alles recht einfach zu halten, wird als Grafik ein ausgefüllter Kreis (
fillcircle) verwendet. Um das Ganze übersichtlicher zu gestalten, wird eine Lua-Tabelle mit dem Namen sprite verwendet, die in dem Beispiel als Struktur fungiert.Zuerst wird ein Fenster geöffnet:
openwindow (640,480,32,"Hello World")
Dies sollte übrigens immer der erste Befehl sein, da damit das gesamte System von EGSL initialisiert wird. Geöffnet wird hier ein Fenster mit einer Auflösung von 640x480 Punkten, 32-Bit Farbtiefe und dem Titel »Hello World«.
Als nächstes wird der Timer eingestellt, damit auf allen Rechnern ein etwa gleich schneller Spielfluss abläuft:
setframetimer (80)
Der Frametimer gibt an, wie viele Bilder pro Sekunde maximal laufen dürfen. Im Gegensatz zu einem 3-D-Spiel will man nicht das maximal Mögliche aus dem System herausholen, sondern gibt eine Beschränkung an. Sonst könnte es sein, dass auf einem sehr schnellen Rechner das Spiel unspielbar wird, da die Logik zu schnell abläuft.
Damit das Sprite später »durchsichtig« wird, wird ein Colourkey gesetzt:
colourkey (0,0,0)
In dem Fall die Farbe Schwarz, d. h. der Rot-, Grün- und Blau-Anteil ist jeweils 0. Das Sprite wird mit der Größe 32x32 angelegt und der X- und Y-Position 320 und 240 positioniert:
sprite={}
sprite.image = createimage (32,32)
sprite.x=320
sprite.y=240
Als nächstes wird das Bild gezeichnet. Es soll ein gelber ausgefüllter Kreis werden:
startimagedraw (sprite.image)
colour (255,255,0)
fillcircle (16,16,15)
stopimagedraw()
Mit startimagedraw() beginnt man, auf einem zuvor erstellten Bild zu zeichnen; in diesem Fall sprite.image. Die Zeichenfarbe wird auf Gelb gesetzt, d. h. ein Rot- und Grünanteil von je 255 und ein Blauanteil von 0. Der Kreis wird mittels fillcircle() auf das sprite.image gesetzt an der X- und Y-Position 16. Der Radius beträgt 15 Bildpunkte.
Danach kann man die eigentliche Spielschleife beginnen lassen, wobei als erstes der Fensterinhalt gelöscht wird:
repeat
cls()
Die Löschung geschieht übrigens bei jedem Durchlaufen, also mehrmals pro Sekunde. (In vorliegenden Fall 80 Mal, da der Frametimer auf 80 eingestellt wurde.)
Mittels
key=getkey()
wird der Variablen key der ASCII-Wert der Funktion getkey() zugewiesen. Wenn keine Taste gedrückt wird, passiert natürlich nichts. Die Taste Escape beendet das Programm (siehe Ende der Repeat-Schleife weiter unten).
Für die Bewegung des gelben Kreises muss man die Pfeiltasten abfragen:
if keystate (274) then
sprite.y=sprite.y+1
end
if keystate (273) then
sprite.y=sprite.y-1
end
if keystate (275) then
sprite.x=sprite.x+1
end
if keystate (276) then
sprite.x=sprite.x-1
end
Man sollte beachten, dass die Funktion keystate nichts mit der Funktion getkey() zu tun hat. keystate gibt vielmehr einen Booleschen Wert (wahr oder falsch) zurück, was es ermöglicht, mehrere Tasten gleichzeitig abzufragen. Ausführlich könnte die Tastenabfrage so aussehen:
if keystate (274) == true then
Danach wird das Sprite an der X- und Y-Position sprite.x und
sprite.y gezeichnet:
putimage (sprite.x, sprite.y, sprite.image)
Mittels
wait (timeleft())
wird dafür gesorgt, dass das Limit des Frametimers eingehalten wird. Der nächste Befehl
redraw()
muss etwas genauer erklärt werden. In EGSL wird alles zunächst in den Doppelbuffer gezeichnet. Erst wenn redraw() aufgerufen wurde, ist der aktuelle Zustand sichtbar, d.h. ohne redraw() bleibt der Fensterinhalt schwarz. (Alternativ kann ab Version 1.4.0 die Funktion sync() benutzt werden – sie fasst die zwei Funktionen wait() und redraw() zusammen.)
Das Ende der Repeat-Schleife bildet
until key==27
Solange nicht die Taste Escape (entspricht Keycode 27) gedrückt wurde, läuft die Schleife weiter.
Der letzte Befehl im Programm sollte immer
closewindow()
sein, da hiermit der belegte Speicher wieder freigegeben und das SDL-System beendet wird. Danach kann wieder ein openwindow() folgen, das aber wiederum mit einem closewindow() beendet werden muss.
Dies war nur ein kleiner Einblick in das, was mit EGSL alles möglich ist. Wer schon einmal mit dem einen oder anderen BASIC-Dialekt gearbeitet hat, wird sich bei EGSL sicher schnell zurecht finden. Das Programm wird kontinuierlich verbessert, es lohnt sich also, öfter mal auf der Internetseite vorbei zu schauen. Leider ist die Dokumentation noch nicht ganz fertig, aber auch daran wird ständig gearbeitet.
Fazit
Wer gerne ein Computerspiel nach Retro-Art programmieren möchte, das eventuell auch multiplattformfähig sein soll, sollte einen Blick auf EGSL werfen. Aufgrund der Einfachheit der Lua-Programmiersprache liegen schnell erste Ergebnisse vor. Dabei eignet sich EGSL nicht nur für Spiele allein: Sogenannte Old-School-Demos mit Laufschrift sind ebenfalls im Nu programmiert.
Hilfe zu EGSL erhält man im (englischsprachigen) Forum. Bei entsprechendem Interesse ist es durchaus vorstellbar, dass ein deutschsprachiges Unterforum eingeführt wird.
Autoreninformation
Markus Mangold ist der Entwickler von EGSL. Er begann im Jahr 1984 mit dem Programmieren auf einem C64 und der Sprache BASIC. Bis heute ist vor allem das Entwickeln von 2-D-Spielen sein Hobby geblieben, am liebsten mit EGSL oder FreePascal.
Dieser Artikel ist in freiesMagazin 07/2011 erschienen. Veröffentlichung mit freundlicher Genehmigung.



