"GESTATTTEN, MEIN NAME IST SPRITE!"
Ein Kurs zum näher Kennenlernen.
Teil 1
Ob MultiColour oder Hires, expanded oder multiplexed, im Border oder nicht im Border; jeder kennt sie: SPRITES! Diese 21 Pixel hohen und 24 Pixel breiten "Grafik-Inhalte" werden oft zu Recht als Kobolde bezeichnet. Denn da sie in Positions-Gebung, Größe und An- zahl äußerst flexibel sind, verschwinden und wieder auftauchen können, wann sie wollen, weisen sie selbige Charakterzüge auf. Und, so meine ich behaupten zu können, gäbe es sie nicht, gäb's den C64 auch nicht mehr. In unzähligen Spielen und ebenso vielen Demos wurde realisiert, was mit den Grafik-Modi (egal ob Text-oder Grafik) niemals(!) möglich gewesen wäre. Ob nun der Held eines Games in Sprites verpackt wurde oder Logos über Landschaften be- wegt wurden; auf größeren Rechnern wie Amiga oder PC ist dies immer mit Grafik- Verschiebung verbunden, was immer viel Rechen-Zeit und-Aufwand bedeutet, wohingegen die DMA des C64 rasterzeit- sparend arbeitet und jegliche Objekte durch Umschalten der Spriteblock-Pointer noch ohne zusätzlichen Zeit-Verlust animiert werden können. Gut,der Titel "Sprites zum Näher-Kennen- lernen" dieses 3teiligen Kurses trifft den Nagel genau auf den Kopf. Wer nämlich noch überhaupt keine Erfahrung mit Sprites hat, sollte dies zuvor unbe- dingt nachholen. Dieser Kurs ist wirklich zum NÄHER(!) Kennenlernen. Erfahrung mit den VIC-(spez. Sprite-) Registern und fortgeschrittene Assembl- er-Kenntnisse sind Vorraussetzung. Beginnen wollen wir mit:
1.JOYSTICK-ABFRAGE UND BESCHLEUNIGTE BEWEGUNG
Unser "Sprite-Demo #1" installiert eine Abfrage in den Raster-Irq, die ein SMILIE-Sprite (auch diese Sorte werden wir näher kennenlernen...) vom Joystick in Port #2 gesteuert über den Bildschirm fliegen läßt. Das Besondere dabei ist die beschleunigte(!) Bewegung in X- als auch in Y-Richtung. Meine Lösung einer beschl.Joystick- Abfrage sieht folgend aus: Horizontal und vertikal verwende ich jeweils einen Pointer (Xpoint,Ypoint), welcher den Index zu einer Tabelle darstellt, aus welcher die eigentliche Geschwindigkeit gelesen wird. Bei Be- tätigung des Joysticks werden nun diese Pointer verändert; um 1 erhöht bzw. um 1 erniedrigt. Sieht dann so aus (in Y-Richtung):
lda $dc00 ;CIA #1=Joystick sta joyst ;speichern and #1 ;Joystick up? bne t5 ;nein, dann t5 lda ypoint ;ja, cmp #1 ;dann ypoint auf #1 beq t10 ;prüfen dec ypoint ;ypoint erniedrigen jmp t10 ;jump t10 t5 lda joyst ;Joystick lesen and #2 ;down ? bne t8 ;nein, dann t8 lda ypoint ;ja, cmp #31 ;dann ypoint auf #31 beq t10 ;prüfen inc ypoint ;ypoint erhöhen bne t10 ;nach t10 (Fortsetzung)
Nun gibt es den Fall, daß weder hinauf noch hinunter beschleunigt wird. Dabei muß eine bestehende Geschwindigkeit ver- mindert werden; es muß GEBREMST werden! Das Programm arbeitet in diesem Fall bei Label t8 weiter... t8 lda #0 ;Y-Bremse:
inc t8+1 ;t8+1 (lda #?) erhöhen and #1 ;bit #0 gesetzt ? bne t10 ;ja, dann keine Bremse lda ypoint ;ypoint prüfen cmp #16 ;mit 16 vergleichen beq t10 ;wenn =16 dann ok bcc t9 ;wenn <16 dann nach t9 dec ypoint ;wenn >16 dann bne t10 ;erniedrigen t9 inc ypoint ;erhöhen t10 ;...Fortsetzung...
Zu Beginn wird der Absolut-Wert, der bei t8 in den Akku geladen wird, erhöht. Somit haben wir einen ständig durch- laufenden Timer. Ist dieser Wert ungerade (also jedes 2.Mal) wird die Brems-Routine nicht ausgeführt. Somit bremst unser Smilie langsamer, als er beschleunigt. Wenn ypoint gleich 16 ist, ist die Y- Bewegung gleich 0 (warum, sehen wir später). Also prüfen wir, ob der Wert kleiner oder größer als 16 ist, und erhöhen bzw.erniedrigen ypoint danach. Funktioniert diese Abfrage und wir haben selbiges auch horizontal für eine X-Bewegung programmiert, so wird der Joystick zwar abgefragt, die Pointer dementsprechend verändert, sogar ge- bremst... doch sichtbar zeigt sich noch GAR NICHTS! Wir wollen nun den Y-und X-Pointer ver- wenden, um dem Sprite Geschwindigkeit zu geben. Dazu müssen wir eine Tabelle anlegen, aus der wir die zum Pointer- Wert entsprechenden "Speeds" lesen und nennen sie "speedtab". Das Ganze zu den aktuellen Sprite-Koordinaten addiert und schon läuft die Sache...
lda ypoint ;Y-Bewegung: clc ;Y-point plus adc #1 ;#1 dazu, lsr a ;dann lsr a ;geviertelt tax ;und ins X-Register lda v+1 ;Sprite #0 Y-Position clc ;dazu Wert aus adc speedtab,x ;Speedtab+x addiert sta v+1 ;schreiben cmp #50 ;Oben Limit: bcs t21 ;größer, dann nicht lda #50 ;Y-Position auf sta v+1 ;#50 setzen lda ypoint ;Ypoint invertieren eor #31 ;und #2 clc ;dazuzählen, adc #2 ;um Bewegung sta ypoint ;umzukehren jmp t25 ;jump t25 t21 cmp #230 ;Unten Limit: kleiner bcc t25 ;als 230, dann nicht lda #230 ;Y-Position auf sta v+1 ;#230 setzen lda ypoint ;Ypoint and #254 ;invertieren, eor #31 ;um Bewegung sta ypoint ;umzukehren t25
In Speedtab stehen positive und negative Werte. In unserem Fall reichen die Speeds von -4 bis +4. Der Pointer-Wert wird zuerst durch 4 geteilt, wobei zuvor #1 dazugezählt wird. Ypoint kann also Werte von 1 bis 32 besitzen, durch 4 geteilt folglich Werte von 0-8. Diese 9 Werte sehen im Byte-Format dann so aus:
speedtab .byte 252...255 ;Negativ-Bereich .byte 0 ;Mitte = 16 = Speed 0 .byte 1,2,3,4 ;Positiv-Bereich
Da wir immer zum Sprite-Y-Register addieren, ergibt ein Operand #255 also -1, #254 dann -2 usw... In X-Richtung gilt selbes Muster wie vertikal. Durch das X-Hi-Byte wird's ein wenig komplizierter, doch ein Blick ins Source-File gibt Verständnis.
2.PROGRAMMIERTES BEWEGEN VON SPRITES
"Sprite-Demo #2" läßt unseren SMILIE eine x-beliebige Bewegung am Bildschirm vollziehen, die er immer wieder neu be- ginnt. Zuerst wird inititalisiert, wobei dem Sprite eine fixe Star-Position zugeordnet wird und die Bewegungs- Pointer zurückgesetzt werden. Aus der Liste "movedats" wird nun aus- gelesen. Und zwar immer fünf Bytes, welche gleich den Adressen up,down,left right und time zugeordnet werden. In "up" steht dann, wieviel Pixel das Sprite nach oben bewegt werden soll, in "down" wieviel nach unten, usw... "time" schließlich gibt an, wie oft dieser Step wiederholt werden soll, bis die nächsten Werte ausgelsen werden. Solange time ungleich 0 ist, werden immer die selben Werte addiert bzw. subtrahiert. Die Liste "movedats" wird mit #255 abgeschlossen, worauf das Programm automatisch den Listenpointer wieder zurücksetzt. Die Bewegung startet da capo. Das X-Hi-Byte ($d010) wird mit der Adresse "xhi" beschrieben. Diese Bewegungs-Routine eignet sich im Besonderen für Spiele, da sich sehr umfangreiche und unregelmäßige Bahnen gestalten lassen. Sie soll nur eine Anregung dazu sein, eigene Routinen zu entwickeln, die speziell für Spiele sehr zweckmäßig sind. Im nächsten Teil gibt's Action(!) mit mehr als 8 Sprites gleichzeitig... Also, bis bald!