Du bist nicht angemeldet.

Lieber Besucher, herzlich willkommen bei: Pixelor. Falls dies dein erster Besuch auf dieser Seite ist, lies bitte die Hilfe durch. Dort wird dir die Bedienung dieser Seite näher erläutert. Darüber hinaus solltest du dich registrieren, um alle Funktionen dieser Seite nutzen zu können. Benutze das Registrierungsformular, um dich zu registrieren oder informiere dich ausführlich über den Registrierungsvorgang. Falls du dich bereits zu einem früheren Zeitpunkt registriert hast, kannst du dich hier anmelden.

henrikf

Pixelor-Team

  • »henrikf« ist der Autor dieses Themas

Beiträge: 6 828

Wohnort: Bad Aibling / Bayern

Beruf: Software-Entwickler

  • Private Nachricht senden

1

08.09.2018, 14:56

Retro Game Programming - Wilde Ideen für ein Shoot'em'Up

Seitdem v3to in seinem Vorstellungs-Thread das Shoot'em'Up Reeshoot R von Richard Löwenstein vorgestellt hat (siehe hier), spukt mir die Idee im Kopf herum, selber ein Shoot'em'Up zu programmieren. Und wie es mit vielen Spielen so ist, beginnt das Ganze ja immer mit einer Idee. Also kann man ja einfach mal herumspinnen und dieses will ich einfach mal zu Protokoll geben.

Ein Shoot'em'Up für den Amiga zu programmieren habe ich nach einigen spinnerten Idee erst einmal verworfen. Zum einen kenne ich mich mit dem Amiga so gut wie nicht aus. Er hat zwar einige Ähnlichkeiten zu der Architektur des Atari 800 (kein Witz, die »Display List« im Atari 800 hat zum Beispiel große Ähnlichkeit zur »Copper List« im Amiga, ist ja auch vom selben Designer), aber trainiert bin ich darin eben nicht. Auch 68000-Assembler habe ich noch nicht wirklich programmiert. Beides traue ich mir zwar zu, zumal sowohl die Hardware des Amiga als auch der 68000er ausgezeichnet dokumentiert sind. Aber man muss ja nicht übertreiben.

Stattdessen wäre die Idee, ein Shoot'em'Up für den Atari 800 zu programmieren. Zum einen gibt es da nicht wirklich viele Spiele und schon gar nicht horizontal scrollende. Und zum anderen ... naja ... ich hätte einfach Bock drauf. Woran ich merke, dass ich tatsächlich Bock drauf habe und es nicht einfach nur eine fixe Idee ist? Nun, ich spiele seit einer Woche mit der Idee, und sie wird immer attraktiver. :D

Also habe ich vorgestern Abend mal schnell einen winzigen Code zusammen gebaut, der einfach nur irgend welche Bildschirminhalte von rechts nach links scrollt, entsprechend der Flugrichtung eines Raumschiffes in solchen Spielen von links nach rechts.

Und schon gehen die Grübeleien los:

Der Atari kann nur 16 Pixel horizontal scrollen. Wenn man einen Modus mit umdefinierten Zeichensätzen für die Hintergrundgrafik nimmt - und das ist im Moment »way to go« für mich - dann hat man bei ATari einen Zeichensatz, der pro Zeichen 4 Pixel horizontal darstellen kann. Die Pixel sind außerdem doppelt so breit wie hoch. Bei 16 Pixel scrollen sind das also genau 4 Zeichen, die da entlangwandern. Will man weiter scrollen, dann gibt es zwei Möglichkeiten:


Methode a)
Der bisherige Bildschirminhalt wird kopiert, in die kommenden nächsten 4 Zeichen wird neuer Inhalt kopiert und die Scrollposition wird wieder auf Null gesetzt. Alle 16 Pixel »ruckt« der Bildschirm also wieder auf seine Ausgangsposition, was man aber als Spieler nicht bemerkt, weil eben der Inhalt entsprechend umkopiert wurde.
Vorteil: Man benötigt nicht viel Speicher im RAM des Atari.
Nachteil: Alle 16 Pixel müssen für einen 8-Bit-Computer vergleichsweise große Datenmengen bewegt werden. Bei 40 Zeichen pro Zeile und 20 Zeilen sind das 800 Byte. Wobei es ja nur 36 Zeichen pro Zeile sind, denn die links heraus gewanderten werden ja nicht mehr benötigt. Also sind es 720 Byte. Man kann grob rechnen, dass der 6502 pro Kopieroperation im Schnitt 6 bis 7 Taktzyklen benötigt (laden, speicher, laden, speicher, zwischendurch mal schauen, ob man schon fertig ist und so weiter). Also kommt man alleine hier schon auf 5.040 Taktzyklen. Und ohne jetzt ins Detail gehen zu wollen: Aber das ist richtig sch*** viel.


Methode b)
Man legt einen endlos langen Bildschirmspeicher an und alle 16 Pixel wird der Bildschirmpointer um 4 Zeichen »nach rechts« verschoben.
Vorteil: Der Prozessor hat deutlich weniger Arbeit als bei Methode a)
Nachteil: Man benötigt viel RAM!


Nachdem ich mich eine Weile mit Methode a) beschäftigt habe, fand ich noch einige weitere Nachteile (ich gehe unten darauf ein). Deswegen ist die für mich eigentlich schon passé.

Der größte Nachteil bei Methode b) ist der Speicherplatz-Bedarf. Das komplette Level muss im Speicher des Atari vorliegen. Tricks wären zwar denkbar, dass zum Beispiel das Level irgendwo stehen bleibt, der Spieler mit einer Aufgabe beschäftigt wird (Boss bekämpfen, Objekten ausweichen, pipapo) und es dann weiter geht. Da kann man prima eine Pause einbauen, in der der zweite Teil des Levels nachgeladen wird. Aber das ist mir zu sehr »das Pferd von hinten aufgezäumt«.

Wobei ... hmmm ... jetzt da, ich darüber nachdenke ... ;) ... ich behalte das mal im Kopf !

Aber bleiben wir mal bei einem kontinuierlich scrollenden Level. Nehmen wir einmal an, nur um irgendwo anzufangen, das komplette Level würde 16 KByte an RAM belegen. Das ist auf dem Atari schon recht viel RAM. Im normalen Betrieb - ohne Ausnutzung von Bank-Umschaltereien und so weiter, die auch nur ab Atari 800 XL zur Verfügung stünden - hat ein Programm nämlich nur 32 KByte RAM zur Verfügung. Der 6502 kann 64 KByte ansprechen. 16 KByte gehen beim Atari für das Betriebssytem drauf, weitere 16 KByte für ein eingestecktes ROM-Modul (ich gehe davon aus, dass das Spiel als Modul verfügbar ist, denn in dieses könnte man 128 KByte an Daten packen). Ergo bleiben 32 KByte übrig. Und die Hälfte verwenden wir bei unserer Annahme ausschließlich für das scrollende Level.

Kurz ein wenig Mathematik: Wenn wir 16 KByte und 20 Bildschirmzeilen mit den Zeichensätzen für die Level-Grafik haben, dann ist jede Zeile 819 Byte bzw. 3.276 Pixel lang. Wenn man pro angezeigten Bildschirm im 60-Hz-Modus (NTSC) ein Pixel scrollt, dann ist man nach rund 54 Sekunden von Anfang bis Ende mit dem Level durch.

Das ist nicht viel. Genau genommen ist es sogar ein lächerlich kurzer Level. Und wie schon erwähnt ist dabei schon das halbe verfügbare RAM drauf gegangen.

Aber zum Glück gibt es einen praktischen Denkfehler, den ich anhand meines winzigen Demo-Programm sehen konnte: Wenn man nämlich wirklich ein Pixel pro Bildschirm scrollt, dann ist das rasend schnell. Ich habe es danach mit einem Pixel alle vier Bildschirme versucht, was immer noch recht zügig ist. Aber schon dann käme man auf ca. 3:38 Minuten pro Level. Das wäre dann schon ordentlich für ein Shoot'em'Up; fast schon zu lang. Und ich bin mir gar nicht sicher, ob man einen Level so interessant gestalten kann, dass der Spieler nicht irgendwann sagt: »Menno ... jetzt reicht's auch mal!« Das darf natürlich auf keinen Fall passieren. Aber nichts hindert mich daran, die Level kürzer zu machen. Ich muss mir mal Videos von »R-Type« und »Gradius/Nemesis« ansehen, wie schnell die scrollen. Aber ich denke, man wird in der Praxis wohl bei 5 oder 6 Pixel pro Bildaufbau landen. Und das würde die Dauer eines Levels noch einmal zusätzlich verlängern.

Noch ein paar Ideen zum Thema Zeichensatz-Grafik gegen Bitmap-Grafik, wo Pixel direkt mit Byte im Speicher verknüpft sind. Mit Zeichensatz-Grafik kann man wunderbar speicherplatzsparend wiederkehrende Strukturen im Level erzeugen: Hügel, Bäume, Häuse, was einem so einfällt. Wenn ein Baum die Grüße eines Zeichens hat (beim Atari 4x8 Pixel, was zugegeben eine Herausforderung für einen Grafiker darstellt), dann braucht jeder Baum nur ein einziges Byte im Speicher. Noch besser: Man verändert die Grafik des Zeichensatzes während des Spiele-Ablaufes und schon bewegt sich der Baum im Wind (auch hier abhängig von den Fähigkeiten des Grafikers).

Zeichensatz-Grafik hat also riesige Vorteile. Und genau deswegen basieren nahezu alle 2D-Konsolen und auch fast alle Automaten-Platinen genau auf diesem Prinzip. Und auch der C64 schöpft einen Teil seiner Power daher. Nur die 16-Bit-Computer von Atari und Commodore (Atari ST und Amiga) habe es nicht implementiert. Aber wer will auf diesen Computern schon spielen? ;) Wobei der Amiga zum Ausgleich einen leistungsfähigen Blitter und Sprites besitzt. Ja, ja, Atari. Aber ich schweife ab.

Jedenfalls ist die Zeichensatz-Grafik auch hier »way to go«. Sie hat auf dem Atari noch den Vorteil, dass man eine 5. Farbe mit ins Spiel bringen kann. Aber das nur am Rande.

Mir schwebt noch etwas im Hinterkopf herum: Ich will die Zeichensatz-Grafik nämlich nicht nur als statische Level-Elemente verwende, sondern auch für Gegner. Das spuken mir Minen im Kopf herum, die beim Abschießen auf den Spieler schießen, oder sie wandern in Richtung des Spielers, wenn man sie anschießt, oder es gibt fetter Brocken, die von oben fallen, oder Plattformen fahren von oben und unten aus und wieder ein, ganz banale Kanonen, die im Level herumstehen und so weiter und so weiter. Das gab es nämlich noch nicht auf dem Atari.

Und jetzt sind wir wieder bei der Methode a) von weiter oben: Wenn ich das Scrolling durch kontinuierliches Umkopieren von Speicherbereichen bewerkstellige, dann wird die Verwaltung solch aktiver Elemente noch einmal deutlich komplizierter. Nee, nee, lieber nicht ... ;)

Noch ein Wort dazu, warum ich Gegner überhaupt mit Zeichensatz-Grafik angehen will und nicht mit den Sprites des Atari (heißen hier »Player« und »Missiles«): Die Grafikfähigkeiten dieser Elemente sind auf dem Atari extrem begrenzt. Und zwar in Anzahl als auch in den Farben. Und ich muss mich außerdem noch um herumfliegende Gegner kümmern.

Jo, das mal auf die Schnelle. Wann ich das ernsthaft durchziehen will ... keine Ahnung. Jetzt wird erst einmal das andere Spiel fertig gestellt. ^^
--== Island2Live / Henrik Fisch==--
Homepage: http://www.island2live.com/ deviantART: http://island2live.deviantart.com/
Spielt gerade: Yonder: The Cloud Catcher Chronicles

2

09.09.2018, 09:58

Die Idee, einen Shmup auf dem Atari XL zu entwickeln, finde ich ja mal spannend. Gerade auch mit der Zeichensatzgrafik, denn die ist auf dem Rechner meines Wissens mit 128 Chars schon ziemlich limitiert, wenn darüber auch noch die Gegner dargestellt werden. Kannst du zur Not über Splits mehrere Zeichensätze auf dem Screen verwenden, um etwas mehr mit dem Hintergrund machen zu können?

henrikf

Pixelor-Team

  • »henrikf« ist der Autor dieses Themas

Beiträge: 6 828

Wohnort: Bad Aibling / Bayern

Beruf: Software-Entwickler

  • Private Nachricht senden

3

09.09.2018, 10:25

[...] Gerade auch mit der Zeichensatzgrafik, denn die ist auf dem Rechner meines Wissens mit 128 Chars schon ziemlich limitiert, [...] Kannst du zur Not über Splits mehrere Zeichensätze auf dem Screen verwenden, um etwas mehr mit dem Hintergrund machen zu können?

Ja, technisch geht das ohne Probleme. Hier käme dann der berühmte »Display List Interrupt (DLI)« zum Einsatz, mit dem man alles im Atari-Computer manipulieren kann (ich glaube genau wie beim »Rasterzeilen-Interrupt« des C64). Denkbar wäre also per DLI in der vertikalen Mitte des Bildschirms den Zeichensatz umschalten, so dass man für die obere Hälfte den einen und für die unteren Hälfte eine zweiten Zeichensatz zur Verfügung hat.

Leider gibt es dann andere Komplikationen. Zunächst einmal will ich Gegner nicht ausschließlich über den Zeichensatz darstellen, sondern nur zusätzlich und nur solche Gegner, die sowieso stationär im Level wären. Also zum Beispiel Kanonen auf dem Boden oder die erwähnten »Suicide-Minen«. Die würden sich also nicht bewegen. Und wenn sie sich bewegen, dann eben nur ruckartig, nämlich jeweils um ein Zeichen in die entsprechende Richtung. Wie gesagt könne man dadurch auch ganz gut zum Beispiel ausfahrende Plattformen animieren. Noch einen entsprechend Soundeffekt drunter (»brrt ... brrt ... brrt«) und schon fällt das Ruckartige gar nicht so auf.

Es soll natürlich trotzdem fliegende flüssig animiert Gegner geben. Dazu würde ich die »Player«-Grafik des Atari nutzen wollen. Die bietet aber pro Player nur eine einzige Farbe (und durchsichtig natürlich). Und da es nur vier Player im Atari gibt und mindestens einer für das Raumschiff benötigt wird (evtl. sogar zwei), wäre ich dann zu limitiert. Sowohl in Anzahl der Gegner als auch in deren Farbigkeit.

Und damit sind wir wieder beim DLI. Damit man überhaupt mehrere als zwei oder drei Gegner darstellen könnte und diese bunt einfärbt, würde ich einen durchgehendes kleines Programm, welches über die Höhe des Spielfeldes läuft nutzen. Das ist quasie ein einziger großer DLI. Für jede Zeile des Spielfeldes wird eine Farbe des Players gesetzt und dessen horizontale Position. Dadurch kann man mit einem einzigen Player mehrere Gegner darstellen (nebenbei bemerkt ist diese Eigenart, das »Player«-Sprite beim Atari über die ganze Bildschirmhöhe zu ziehen die selbe wie beim Amiga; dort laufen Sprites auch über die komplette Höhe des Bildschirms).

Das Problem dabei ist, dass man während der Dauer einer Bildschirmzeile nur sehr wenige nutzbare Taktzyklen hat. Eine einzige Manipulation von irgendwas (z.B. Farbe) ist kein Problem. Eine zweite Manipulation ist auch noch OK (z.B. horizontale Position des Players). Eine dritte wird schon schwierig. Eine vierte ist praktisch kaum noch machbar. Und deswegen ist das Umschalten des Zeichensatzes in der Theorie kein Problem. In der Praxis aber schwierig zu bewerkstelligen (weil ich sowieso schon zwei Manipulationen pro Bildschirmzeile durchführen muss).

Es gibt noch eine kleine technische Spielerei beim Atari, welche direkt mit der Limitierung der 128 Zeichen zu tun hat. Zur Kodierung der Zeichen werden ja nur 7 Bit benötigt. Wenn man das achte Bit setzt, dann wird für eine Bit-Kombination (ich weiß gerade nicht welche) eine andere Farbe genutzt. So bekommt man mit Zeichensatz-Grafik fünf Farben auf den Bildschirm des Atari. :)
--== Island2Live / Henrik Fisch==--
Homepage: http://www.island2live.com/ deviantART: http://island2live.deviantart.com/
Spielt gerade: Yonder: The Cloud Catcher Chronicles

4

09.09.2018, 12:06

Wie gesagt könne man dadurch auch ganz gut zum Beispiel ausfahrende Plattformen animieren. Noch einen entsprechend Soundeffekt drunter (»brrt ... brrt ... brrt«) und schon fällt das Ruckartige gar nicht so auf.


Um das Ruckartige zu kaschieren, müsste aber ein "brrrrrrrrrrrrrrrrt" sein ;)
Sir Pommes: "What the Fatsch!"