Moin,
ich schreibe gerade ein Spiel für den VC20. Da es hier keine Sprites gibt, werden alle Spielergrafiken als Characterzeichen dargestellt und bei Bewegung bitweise auf ihr Ziel verschoben.
Jede Figur hat ein fest zugewiesenes Characterzeichen (hier A) und für die Bewegungsanimation jeweils ein festes Zeichen, dass für das Verschieben benutzt wird (hier B).
Bewegt sich die Figur nicht, wird sie immer nur mit dem Zeichen A abgebildet.
B ist immer %00000000 und dient nur als temporäres Zeichen um die bittweise Verschiebung abzubilden.
Jede Figur bindet also immer ein Characterpärchen (AB, CD, EF,...).
Der Bewegungsablauf findet über diese 5 Schritte statt:
- B wird auf die Zielposition geschrieben
- Die Bewegung wird durchgeführt (siehe Code)
- Auf dem BS wird B durch A ersetzt
- Die ursprünglichen Bits werden von B auf A zurückkopiert (unsichtbar)
- Alle Bits auf B werden gelöscht (unsichtbar).
Das ist nötig weil der Character, wenn er sich nicht bewegt, immer das Zeichen A abgebildet wird.
Hier mein Codeschnipsel, mit dem ich die Bewegungen Hoch, Runter, Rechts, Links abbilde.
Es funktioniert so, dass ich das aktuelle Characterzeichen über die Zeropage (zp) auf ein Zielzeichen (zp2) bitreise verschiebe.
Also, Zeichen A wandert Bit für Bit auf Zeichen B.
- !zone shift_char2tmp ; Dieser Code wird pro Zeichen 8x durchlaufen !!!!!!!!!!!!!!!!!!!
- shift_char2tmp lda ACTION
- bne .shift_char2tmp
- rts
- .shift_char2tmp lda #$18 ; High Byte für die Adressen
- sta zp+1
- sta zp2+1
- ldy character_no
- lda lowbyte_tmp,y
- sta zp2 ; LowByte für das Ziel
- lda lowbyte_char,y
- sta zp ; LowByte für die Ausgangsposition
- ldy #7
- lda DIR ; Bewegungsrichtung laden
- ; -------- rechts --------
- .player_dir_right cmp #RECHTS
- bne .player_dir_left
- .scroll_r lda (zp),y
- lsr
- php
- sta (zp),y
- lda (zp2),y
- plp
- ror
- sta (zp2),y
- dey
- bpl .scroll_r
- jmp .end
- ; -------- links --------
- .player_dir_left cmp #LINKS
- bne .player_dir_down
- .scroll_l lda (zp),y
- asl
- php
- sta (zp),y
- lda (zp2),y
- plp
- rol
- sta (zp2),y
- dey
- bpl .scroll_l
- jmp .end
- ; -------- runter --------
- .player_dir_down cmp #UNTEN
- bne .player_dir_up
- .scroll_d
- ldy #7
- lda (zp),y ; Byte 7 ...
- tax ; ... auf X zwischenspeichern
- dey
- .loop_down lda (zp),y ; hole CHAR-Zeile 6 ...
- pha ; ... auf den Stack
- lda (zp2),y ; hole TMP-Zeile 6 ...
- iny
- sta (zp2),y ; ... speichere sie auf 7
- pla ; hole TMP-Zeile vom Stack...
- sta (zp),y ; ... speichere sie auf CHAR-7
- dey
- dey
- bpl .loop_down
- ldy #0
- txa ; Byte 7 aus dem X-Reg ...
- sta (zp2),y ; ... auf Ziel Byte 0 schreiben
- tya
- sta (zp),y
- jmp .end
- ; -------- hoch --------
- .player_dir_up cmp #OBEN
- ldy #0
- lda (zp),y ; Byte 0 ...
- tax ; ... auf X zwischenspeichern
- iny
- .loop_up lda (zp),y ; hole CHAR-Zeile 1 ...
- pha ; ... auf den Stack
- lda (zp2),y ; hole TMP-Zeile 1 ...
- dey
- sta (zp2),y ; ... speichere sie auf 0
- pla ; hole TMP-Zeile vom Stack...
- sta (zp),y ; ... speichere sie auf CHAR-0
- iny
- iny
- cpy #8
- bne .loop_up
- ldy #7
- txa ; Byte 0 aus dem X-Reg ...
- sta (zp2),y ; ... auf Ziel Byte 7 schreiben
- lda #0
- sta (zp),y ; Byte 0 vom CHAR löschen
- .end rts
Nicht wundern, die Funktion verschiebt das Zeichen immer nur um einen Pixel je Richtung, wird aber 8 mal durchlaufen.
Der Code funktioniert, fühlt sich aber umständlich an.
Aktuell benötige ich hierfür 145 Bytes.
Wie lässt sich diese Funktion optimieren und verkürzen?
Hoffentlich konnte ich mein "Konzept" hier verständlich beschreiben.
aitsch