Magic Disk 64

home to index to text: KURS-SPRITE KURS.txt
   "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 Anzahl ä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 Textoder Grafik) niemals( !) möglich gewesen wäre. Ob nun der Held eines Games in Sprites verpackt wurde oder Logos über Landschaften bewegt 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 rasterzeitsparend 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 3 teiligen Kurses trifft den Nagel genau auf den Kopf. Wer nämlich noch überhaupt keine Erfahrung mit Sprites hat, sollte dies zuvor unbedingt nachholen. Dieser Kurs ist wirklich zum NÄHER( !) Kennenlernen.
Erfahrung mit den VIC-( spez. Sprite-) Registern und fortgeschrittene Assembler- 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 Xals 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 Betä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 vermindert 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 durchlaufenden 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 gebremst. . . doch sichtbar zeigt sich noch GAR NICHTS!
Wir wollen nun den Yund X-Pointer verwenden, 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 xbeliebige Bewegung am Bildschirm vollziehen, die er immer wieder neu beginnt. 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 ausgelesen. 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!

Valid HTML 4.0 Transitional Valid CSS!