Ein Herz für selbst programmierte Retro-Games
Ich habe ein Spiel für den Commodore 64 programmiert. In Basic – der Programmiersprache, die der C64 von Haus aus spricht. Das war eine Menge Arbeit, hat aber extrem viel Spass gemacht.
Die Idee muss sich verrückt anhören. Ein Spiel selber zu entwickeln, okay. Aber für den Commodore 64 und dann noch in Basic? Entstanden ist das Vorhaben aus reiner Nostalgie. Die Sehnsucht nach meinen ersten Erfahrungen mit Computern hat mich dahin zurückgeführt. Und ich merke schnell: Es macht mir genauso viel Spass wie damals, in den späten 80er-Jahren.
Damals programmierte ich nicht auf einem Commodore 64, sondern auf einem Kindercomputer, der nur Text anzeigen konnte. Von Grafik konnte ich nur träumen. Das Programmieren eines Spiels mit Grafik ist für mich darum die Erfüllung eines Bubentraums.
Von der ersten vagen Idee bis zum fertigen Spiel verstreichen unzählige Stunden. Ich opfere fast einen Monat lang einen Grossteil meiner Freizeit. Obwohl das Spiel sehr bescheiden ist, empfinde ich es nicht als Zeitverschwendung. Ich bin sogar ein bisschen stolz auf das Ergebnis.
Das Spielprinzip ist simpel. Du steuerst mit den WASD-Tasten ein Herz. Dein Ziel ist das Tor in der gegenüberliegenden Ecke, dabei musst du Bösewichten und Hindernissen ausweichen.
Es ist schwierig, die Faszination meines Projektes zu erklären. Nostalgie spielt nur am Rande eine Rolle. Viel wichtiger: So ein Programm ist eine grosse Denkaufgabe, die sich in viele kleine aufteilt. Jede gelöste Teilaufgabe bringt mich näher ans Ziel und ist sofort sicht- und spielbar. Das motiviert.
Vor allem ist es ein befriedigendes Gefühl, etwas von Grund auf selbst zu machen. Ohne vorgefertigte Teile und Hilfsmittel, wie das auf einem modernen Computer der Fall wäre. Es ist alles komplett selbst erarbeitet.
Im folgenden zeige ich dir, wie aus der ersten Idee nach und nach das fertige Spiel wurde.
Voraussetzungen: Tasteneingabe und Platzierung
Zunächst muss das Programm erkennen, wenn du eine bestimmte Taste drückst, und darauf sofort reagieren. Dazu ist der Basic-Befehl GET K$
da. Er speichert die momentan gedrückte Taste in der Variable K$. Als Kind kannte ich nur den Befehl INPUT
. Damit sind keine Echtzeit-Spiele möglich, weil der Computer erst reagiert, wenn du nach dem Tippen die Return-Taste gedrückt hast.
Element frei platzieren
Die zweite Voraussetzung ist, dass ich ein Element frei auf dem Bildschirm platzieren kann. Das ist selbst bei Text nicht selbstverständlich. Der Befehl PRINT
schreibt den Text dorthin, wo der Cursor ist – einen Basic-Befehl zum Setzen des Cursors kennt der C64 nicht. Daher muss ich mit dem Befehl POKE
eine bestimmte Adresse im Registerspeicher des Chips ändern.
Grafik als Text
Ironischerweise besteht mein erster Versuch eines grafischen Spiels aus Text. Zu sehen sind nichts als zwei Sonderzeichen in Form von Herzchen. Das blaue Herz muss das rote fangen.
Bewegt sich das Herz, muss es nicht nur am neuen Ort ausgegeben, sondern auch am alten gelöscht werden. Ich löse das, indem bei jedem Programmdurchgang – sozusagen bei jedem Frame – erst ein Leerzeichen geschrieben wird und dann das Herz an der neuen Position. Darum flackern die Herzchen.
Diese Vorstufe des Spiels umfasst nur 41 Zeilen Code. Das rote Herz bewegt sich nach dem Zufallsprinzip und ist darum leicht zu erwischen.
Richtige Grafik mit Sprites
Ein Sprite ist ein grafisches Element, das sich auf dem Bildschirm frei bewegt. Anders als bei meinem Textherzchen aktualisiert der Computer den Hintergrund von selbst. Das heisst, ich muss den Sprite nicht jedes Mal löschen, wenn ich ihn an eine neue Stelle bewege.
Zudem kann ich das Aussehen des Sprite frei gestalten. Beim C64 besteht ein einfarbiges Sprite aus 504 Pixeln (21 Zeilen und 24 Spalten). Es gibt auch mehrfarbige Sprites, aber ich will es für den Anfang nicht übertreiben.
Ohne Hilfsmittel ist die Erstellung eines Sprite extremst mühsam. Um den Sprite auf den Bildschirm zu zaubern, muss ich wieder die Speicheradressen des C64 bearbeiten. Dabei muss ich die Werte Pixel für Pixel berechnen. Zum Glück gibt es das C64-Wiki und das sehr gute C64-Benutzerhandbuch, die mir die nötigen Infos liefern.
Ein Sprite-Editor wäre beim Zeichnen und Berechnen eine grosse Hilfe. Ich bin allerdings ungeduldig und will mein erstes Sprite sofort haben. Darum erstelle ich es manuell.
Ich wollte eigentlich ein gebrochenes Herz zeichnen. Es sieht nun zwar aus wie ein Arsch, passt aber auch.
Was mir nicht passt: Das Game läuft quälend langsam. Obwohl es extrem simpel ist. So kann ich es kaum verbessern oder interessanter gestalten, denn dadurch würde es noch langsamer.
Kompilieren in Maschinensprache
Die Lösung ist überraschend einfach: Basic-Programme lassen sich mit einem Compiler automatisch in Maschinensprache übersetzen. Dadurch wird das Programm viel schneller. Ich probiere den Compiler Basic Boss aus, und es klappt auf Anhieb.
Doch auch mit akzeptabler Geschwindigkeit macht mir das Spiel keinen Spass. Es kommt mir noch öder vor als die Textversion. Das Herz bewegt sich nicht mehr zufällig, sondern flüchtet vor mir und kann auch zum gegenüberliegenden Spielrand springen. Aber das reicht nicht, um das Spiel interessant zu machen.
Ich beschliesse daher, die Rollen zu tauschen: Als Spieler muss ich jetzt nicht mehr fangen, sondern davonrennen. Damit es nicht zu simpel wird, gibt es zwei Figuren, vor denen ich flüchten muss. Und weil das mit lauter Herzen seltsam aussieht, brauche ich ein neues Sprite. Eines für den Bösewicht. Und vielleicht auch ein neues für das gebrochene Arschherz.
Durch das Kompilieren ist das Spiel zwar viel schneller als in Basic, aber immer noch langsam. Sobald ich es komplexer mache, läuft es wieder schnarchig. Den nötigen Boost bringen mir sogenannte Compiler-Direktiven. Das sind als Kommentarzeilen im Basic-Programm untergebrachte Hinweise für den Compiler. Dadurch kann ich zum Beispiel kleine, ganzzahlige Variablen als solche deklarieren, wodurch das Rechnen viel schneller geht. Mittlerweile habe ich die Geschwindigkeit so weit optimiert, dass ich das Game gar nicht mehr schaffe. Aber vielleicht schaffst du es ja – du kannst es hier herunterladen. Die entzippte .d64-Datei kannst du in das Drag-and-Drop-Feld des Online-Emulators ziehen.
Ich bastle einen Sprite-Editor
Da ich keine Lust habe, von Hand eine weitere Grafik auszurechnen, entscheide ich kurzerhand, einen Sprite-Editor zu programmieren. Das ist zwar noch viel mehr Arbeit, macht aber Spass.
Dieses Stück Software ist alles andere als perfekt, aber es erfüllt den Zweck. Hat auch nur ein komplettes Wochenende gedauert, den Editor zu programmieren. Dabei habe ich eine Menge über das Laden und Speichern auf dem C64 gelernt. Und ich weiss jetzt, wie ich den kompletten Bildschirm zwischenspeichern und später wiederherstellen kann. Das kann ich sicher später mal gebrauchen.
Kollisionskontrolle
Da du im Spiel nicht mehr ein Herz fangen, sondern flüchten musst, braucht das Game ein neues Ziel. Ich mache es mir auch da wieder so einfach wie möglich: Die Spielfigur muss eine kleine Lucke erreichen, ohne erwischt zu werden. Um den Schwierigkeitsgrad etwas zu erhöhen, platziere ich einige Hindernisse.
Der C64 hat eine eingebaute Kollisionserkennung. Durch die Abfrage des Werts von zwei bestimmten Speicherregistern weiss mein Programm, ob die Spielfigur mit einem Bösewicht respektive den Hindernissen kollidiert.
Mehrere Levels und mehrere Leben
Als nächstes will ich mehrere Levels machen. Das geht mit wenig Aufwand. Im Prinzip brauche ich lediglich ein paar Variablen wie Startposition der Figuren oder Hindernisse zu ändern und dann das Programm neu durchlaufen zu lassen.
Viel schwieriger ist es, die Level so zu justieren, dass sie weder zu leicht noch unlösbar sind. Denn ich kann das Spiel nur kompiliert in der korrekten Geschwindigkeit spielen und muss daher nach jeder Änderung neu kompilieren, um es auszuprobieren. Im Emulator kann ich zwar die CPU beschleunigen, aber das bringt nur einen groben Eindruck, es ist nicht dasselbe.
Bei acht Levels ist es fair, wenn ich als Spieler mehrere Leben erhalte. Diese werden rechts in Form von Herzchen angezeigt – das Textherz ist zurück!
Zudem braucht das Game einen Start- und Endbildschirm. Auch hier mache ich es mir wieder einfach und blähe die Sprites in der Grösse auf. Der C64 kann dies von Haus aus. Wenn du alle acht Level geschafft hast, erscheint zudem eine kleine Animation. Damit hat das Spiel alle grundlegenden Elemente.
Fazit: gar nicht so simpel
In der hier gezeigten Form hat das Programm etwa 240 Zeilen. Selbst in einem völlig simplen Spiel steckt bereits einiges an Arbeit, Überlegungen und Konzepten. Zumindest, wenn du das Spiel von Grund auf selbst machst. Jetzt, wo ich das Fundament habe, kann ich es relativ leicht erweitern: Mehr Levels anfügen, andere Sprites einbauen und neue Gegner mit anderen Laufwegen programmieren. Daneben gäbe es auch komplexere Erweiterungen: Etwa, dass die Gegner Hindernissen ausweichen oder an ihnen zerschellen. Dass die Figuren bei bestimmten Ereignissen ihr Aussehen ändern. Ein komplett eigenes Thema wären Musik und Soundeffekte.
Mir wird so schnell nicht langweilig. Ich hoffe nur, dass der ganze Wahnsinn gleichzeitig mit dem Winter zu Ende sein wird.
Hier nochmal der Download-Link: Herzschmerz für den C64
Durch Interesse an IT und Schreiben bin ich schon früh (2000) im Tech-Journalismus gelandet. Mich interessiert, wie man Technik benutzen kann, ohne selbst benutzt zu werden. Meine Freizeit ver(sch)wende ich am liebsten fürs Musikmachen, wo ich mässiges Talent mit übermässiger Begeisterung kompensiere.