Sprite
Ein Sprite (englisch, bedeutet "Kobold" oder "Geist") ist ein auf dem Bildschirm frei bewegbares Grafikelement. Beim C64 hat ein Sprite eine maximale Punktgröße von 24 × 21 Pixel (HiRes) und eine Speichergröße von 63 Bytes. Durch die hohe Flexibilität und Verarbeitungsgeschwindigkeit sind Sprites besonders in Spielen populär, z.B. für Spielfiguren oder Gegner. Auch genutzt werden Sprites zur Darstellung eines Mauszeigers oder Steuerpfeils als Pixelcursor (z.B. in Anwendungen mit GUI zur Bedienung von Fenstermenüs), als Ersatz für den Zeichen-basierten Textcursor oder für die Darstellung von Icons.
Einführung[Bearbeiten | Quelltext bearbeiten]
Die Verwaltung der Sprites, die Festlegung der Sprite-Eigenschaften (z.B. Farbe, Größe, Kollisions- oder Prioritätsverhalten) und die Steuerung der Sprites erfolgt über den Grafikchip VIC-II im C64. Dieser unterstützt die Darstellung von maximal acht Sprites, entweder in einem hochauflösenden einfarbigen Modus (Hires; 24×21 Pixel[1]; eine aus 16 möglichen Farben pro Sprite) oder einem Mehrfarben-Modus (Multicolor; 12×21 Pixel; drei aus 16 möglichen Farben plus Hintergrundfarbe, wobei zwei Farben allen Sprites gemeinsam sind). Durch spezielle Programmiertechniken, bei denen das Timing auf den Rasterstrahl abgestimmt wird, können mehr als acht Sprites gleichzeitig angezeigt werden, sogenannte "Sprite-Multiplexing". Sprites haben eine Aktionsfläche von 512×256 Pixels, wobei das Standard-Bildschirmfenster nur einen Teilbereich dieser Aktionsfläche darstellt.
Sprite-Daten[Bearbeiten | Quelltext bearbeiten]
Ein Sprite-Block besteht immer aus 63 Byte Daten und einem Platzhalter-Byte am Ende, also insgesamt 64 Byte. Jedes Byte besteht aus acht Bits, die eine Wertigkeit von 128, 64, 32, 16, 8, 4, 2, 1 aufweisen.
Die Spritedaten sind folgendermaßen aufgebaut:
Byte 1 | Byte 2 | Byte 3 |
Byte 4 | Byte 5 | Byte 6 |
... | ... | ... |
... | ... | ... |
Byte 61 | Byte 62 | Byte 63 |
Die Konstruktion von Sprites ist von Hand recht mühsam, so dass es hierzu bequeme Sprite-Erstellungsprogramme (Sprite-Editoren) gibt. In BASIC-Erweiterungen (wie z.B. Super Expander 64, Supergrafik, Simons' BASIC) oder in BASIC 7.0 gibt es oftmals eingebaute Sprite-Editoren oder anderweitige Hilfen für die Erstellung von Sprites. Beispielsweise ruft der BASIC-Befehl SPRDEF des BASIC 7.0 am C128 (oder beim Super Expander 64) einen Sprite-Editor auf.
Programmierung in BASIC[Bearbeiten | Quelltext bearbeiten]
Die Sprite-Daten werden sinnvollerweise in DATA-Zeilen abgelegt und mit Hilfe einer FOR-NEXT-Schleife, dem READ-Befehl und POKE-Befehl in den Speicher geschrieben:
10 SZ = 12288: REM Sprite-Block 192 20 FOR X=0 TO 62: READ Y: POKE SZ+X,Y: NEXT X 30 DATA 255, 128, 16: REM 1. Datenreihe ...(Hier werden 19 weitere DATA-Zeilen eingefügt) 50 DATA 255, 128, 16: REM 21. Datenreihe
Sprite-Datenzeiger[Bearbeiten | Quelltext bearbeiten]
Speicheradresse dez. / hex. |
Funktion |
---|---|
2040 / $07F8 | Sprite-Datenzeiger für Sprite 0 |
2041 / $07F9 | Sprite-Datenzeiger für Sprite 1 |
2042 / $07FA | Sprite-Datenzeiger für Sprite 2 |
2043 / $07FB | Sprite-Datenzeiger für Sprite 3 |
2044 / $07FC | Sprite-Datenzeiger für Sprite 4 |
2045 / $07FD | Sprite-Datenzeiger für Sprite 5 |
2046 / $07FE | Sprite-Datenzeiger für Sprite 6 |
2047 / $07FF | Sprite-Datenzeiger für Sprite 7 |
- Es gibt acht Sprite-Datenzeiger (Sprite-Pointer), die jeweils ein Byte lang sind und einem Sprite zugeordnet sind.
- Dieser Zeiger hat einen Wertebereich von 0 bis 255 und gibt an, wo sich die Sprite-Daten im Speicher befinden. Die Sprite-Adresse ergibt sich aus der Multiplikation des Zeigers mit 64.
- In jeder 16 KByte großen VIC-Bank gibt es daher 256 mögliche Sprite-Blöcke zu je 64 Bytes (16*1024=64*256). Für 8 Sprites benötigt man einen Speicher von 8*64 = 2*256 = 512 Bytes, also 2 Pages.
Speicheradressen
Die Sprite-Datenzeiger liegen immer in den letzten acht Bytes des 1 KByte (1024 Byte) großen Bildschirmspeichers.
Im Normalfall (Standardkonfiguration nach dem Einschalten) liegen die Adresswerte bei 2040-2047 ($07F8-$07FF).
Anmerkung: Wird die Lage des Bildschirmspeichers verschoben bzw. die VIC-Bank umgeschaltet, verändert sich auch die Lage der Sprite-Datenzeiger.
Zeichensatz-ROM überlagert Spritedaten
Der VIC sieht in zwei Adressbereichen immer nur das Charakter-ROM anstelle des RAM-Inhalts. In die folgenden Adressbereiche können also keine Sprites gelegt werden:
- 4096 bis 8191 ($1000 bis $1fff) - VIC-Bank 0
- 36864 bis 40959 ($9000 bis $9fff) - VIC-Bank 2
Es gilt daher: In VIC-Bank 0 und 2 können die Sprite-Blöcke 64 bis 127 ($40 bis $7f) nicht verwendet werden. Ist der VIC jedoch auf Bank 1 oder 3 konfiguiert, besteht keine Einschränkung.
Sprite-Blöcke
Ist die VIC-Bank in Standardeinstellung 0, kann man in Assembler je nach sonstiger Nutzung der Zeropage relativ frei die Sprite-Blöcke wählen. In BASIC darf Sprite-Block 11 bedenkenlos verwendet werden. Die Sprite-Blöcke 13 bis 15, die im Kassettenpuffer ($033C) liegen, können ebenfalls benutzt werden.
Bei "kleineren" BASIC-Programmen können auch die obersten Blöcke (255, 254, ...) mit der Speicheradresse (16320, 16256, ...) abwärts verwendet werden. Hier ist aber Vorsicht geboten, da das BASIC-Programm samt Variablen in Richtung aufsteigender Adressen und bei Verwendung von Strings der sich ausdehnende String-Heap früher oder später von höheren Adressen absteigend die Sprite-Daten überschreiben können.
Beispiel
Ein Sprite-Block liegt im RAM-Speicher ab Adresse 832 und soll für Sprite 0 verwendet werden.
→ Der Sprite-Datenzeiger hat daher den Wert 13 (= 832/64).
POKE 2040,13
Sprite ein- und ausschalten[Bearbeiten | Quelltext bearbeiten]
Im Register $D015 (53269) stellt jedes Bit einen "Schalter" dar, der eines der acht Sprites (0 bis 7) einschaltet (Bit = "1") oder ausschaltet (Bit = "0"). Das niederwertigste Bit (Bit 0) gehört zu Sprite 0, das höchstwertigste (Bit 7) zu Sprite 7
Sprite-Nummer: | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Wertigkeit: | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
Beispiele[Bearbeiten | Quelltext bearbeiten]
- Alle Sprites aktiv - die Summe der Bit-Werte wird gesetzt, also 255:
POKE 53269,255
- Nur Sprite 0 (Bit-Wert 1) ein:
POKE 53269,1
- Nur Sprites 0 (Bit-Wert 1) und Sprite 1 (Bit-Wert 2) ein:
POKE 53269,3
- Nur Sprite 3 (Bit-Wert 8) und Sprite 5 (Bit-Wert 32) ein:
POKE 53269,40
- Alle Sprites aus - gesetzt wird der Wert 0:
POKE 53269,0
Sprites positionieren[Bearbeiten | Quelltext bearbeiten]
Sprite- Nummer |
Register X-Position: 0-255 |
Register Y-Position: 0-255 |
---|---|---|
0 | 0 / 53248 / $D000 | 1 / 53249 / $D001 |
1 | 2 / 53250 / $D002 | 3 / 53251 / $D003 |
2 | 4 / 53252 / $D004 | 5 / 53253 / $D005 |
3 | 6 / 53254 / $D006 | 7 / 53255 / $D007 |
4 | 8 / 53256 / $D008 | 9 / 53257 / $D009 |
5 | 10 / 53258 / $D00A | 11 / 53259 / $D00B |
6 | 12 / 53260 / $D00C | 13 / 53261 / $D00D |
7 | 14 / 53262 / $D00E | 15 / 53263 / $D00F |
Sprite- Nummer |
Register X-Position (MSB-Bit mit Wertigkeit 256) | |
0-7 | 16 / 53264 / $D010 |
Jedes der acht Sprites kann punktgenau am Bildschirm positioniert werden. Hierzu stehen 512 mögliche X- und 256 mögliche Y-Positionen zur Verfügung. Der Bezugspunkt eines Sprites ist immer die obere linke Ecke des 24×21-Punktebereichs, ganz egal welche Pixel gesetzt sind.
Vertikale Positionierung[Bearbeiten | Quelltext bearbeiten]
Das Y-Positionsregister der Sprites kann Zahlen von 0 bis 255 erfassen, von denen 200 im sichtbaren Bereich liegen.
Y-Wertebereich normale Sprite-Größe |
Y-Wertebereich doppelte Sprite-Größe |
Beschreibung |
---|---|---|
0-29 | 0-8 | Der obere Rahmen überdeckt komplett das Sprite. |
30-49 | 9-49 | Der obere Rahmen überdeckt teilweise das Sprite. |
50-229 | 50-208 | Das Sprite erscheint zur Gänze. |
230-249 | 209-249 | Der untere Rahmen überdeckt teilweise das Sprite. |
250-255 | 250-255 | Der untere Rahmen überdeckt komplett das Sprite. |
Anmerkung: Diese Tabelle gilt für den 25-Zeilen-Modus. Im 24-Zeilen-Modus verkleinert sich der sichtbare Bereich oben und unten um jeweils vier Pixel.
Horizontale Positionierung[Bearbeiten | Quelltext bearbeiten]
Durch Hinzunahme eines Extra-Bits mit der Wertigkeit 256 in Register (53264/$D010) hat ein Sprite nun 504 (PAL) bzw. 512 (NTSC) mögliche Positionen in der X-Richtung (links/rechts) von denen 320 im sichtbaren Bereich liegen.
X-Wertebereich normale Sprite-Größe |
X-Wertebereich doppelte Sprite-Größe |
Beschreibung |
---|---|---|
0 | 480 (PAL) / 488 (NTSC) | Der linke Rahmen überdeckt komplett das Sprite. |
1-23 | 481-503 (PAL) / 489-511 (NTSC), 0-23 | Der linke Rahmen überdeckt teilweise das Sprite. |
24-320 | 24-296 | Das Sprite erscheint zur Gänze. |
321-343 | 297-343 | Der rechte Rahmen überdeckt teilweise das Sprite. |
344 | 344 | Der rechte Rahmen überdeckt komplett das Sprite. |
Anmerkung: Diese Tabelle gilt für den 40-Spalten-Modus. Im 38-Spalten-Modus verkleinert sich der sichtbare Bereich links um 7 und rechts um 9 Pixel.
Diagramme[Bearbeiten | Quelltext bearbeiten]
Vergleich der Sprite-Koordinaten sx, sy mit den Bitmap-Koordinaten bx = 0...319, by = 0...199:
sx = bx + 24 sy = by + 50
Eckpunkte:
0,0 319,0 24,50 343,50 0,199 319,199 24,249 343,249
Sprite-Koordinaten und Raster-Koordinaten
Auf Grund der Art, wie der VIC Sprites darstellt, muss die Y-Koordinate von Sprites um 1 niedriger sein, als die Nummer der Rasterzeile. Die X-Koordinate dagegen stimmt überein. In "Raster-Koordinaten" beginnt daher also der sichtbare Bildschirmbereich bei (24,51). Siehe dazu die Abbildung in PAL.
Sprite PAL-Lücke und doppelte Anzeige[Bearbeiten | Quelltext bearbeiten]
Hat eine Sprite-Koordinate ihren maximalen Wert erreicht, fängt sie bei einer weiteren Erhöhung wieder bei 0 an. Deshalb erscheint ein Sprite, das an dem einen Rand verschwindet, am gegenüberliegenden wieder. Die maximale X-Koordinate ist 511. Ist ein Sprite hier positioniert, kann es mit doppelter Breite (48) bis Position 46 reichen. Weil der sichtbare Bereich bei X=24 beginnt, erscheint für X-Werte von 481 bis 503 ein "Doppelgänger" an der linken Bildschirmseite, während das "Original" auf der rechten Seite unsichtbar bleibt.
- PAL-Lücke: Ein Sprite hat 9 Adress-Bits für die X-Koordinate, kann also an 512 verschiedene X-Positionen (0...511) platziert werden. Auf einem PAL-C64 mit 63 Zyklen pro Rasterzeile sind aber nur 63×8 = 504 X-Positionen vorhanden. Daher werden Sprites mit X-Koordinaten >= 504 nicht angezeigt.
- Doppelte Anzeige: Für die Y-Koordinate steht nur 1 Byte zur Verfügung mit Werten von 0 bis 255. Auf einem PAL-C64 gibt es aber 312 Rasterzeilen (0 bis 311), so dass die Zeilen 256 bis 311 durch die Y-Werte 0 bis 55 dargestellt werden. In diesem Bereich kommt es daher zu einer doppelten Darstellung des Sprites, die allerdings nur sichtbar wird, wenn man den oberen und unteren Rand öffnet.
Mit dem Programm "movesprite" (Kapitel Siehe auch) kann man sich das anschauen.
Beispiel[Bearbeiten | Quelltext bearbeiten]
- Sprite 5 soll auf X=300 (256+44) positioniert werden.
- Die anderen Sprites sollen ihre momentane X-Position beibehalten.
10 POKE 53258,44 :REM X-POSITION SPRITE 5 = 44 20 POKE 53264,PEEK(53264) OR 32 :REM EXTRA-BIT FÜR SPRITE 5 EIN
LDA #44 STA $D00A ; X-Position Sprite 5 auf 44 setzen LDA $D010 ; Lade X-MSB ORA #%00100000 ; Extra-Bit für Sprite 5 einschalten STA $D010 ; Schreibe X-MSB-Register
Sprites vergrößern[Bearbeiten | Quelltext bearbeiten]
Sprite-Nummer | Registernummer / dez. / hex. | Funktion |
---|---|---|
0-7 | 29 / 53277 / $D01D | Sprite-Größe horizontal (X) verdoppeln |
0-7 | 23 / 53271 / $D017 | Sprite-Größe vertikal (Y) verdoppeln |
Der VIC-II-Chip hat die Fähigkeit, die Sprite-Größe in vertikaler und/oder horizontaler Richtung zu verdoppeln. Die Auflösung nimmt dabei nicht zu, lediglich das Sprite wird zweimal so hoch und breit dargestellt.
- Bit=0 bedeutet Normalgröße.
- Bit=1 bedeutet Vergrößerung.
Der Bezugspunkt des Sprites ist wie immer oben links.
Die einzelnen Bits dieser beiden Register haben folgende Gewichtung:
Sprite-Nummer: | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Wertigkeit: | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
Beispiel[Bearbeiten | Quelltext bearbeiten]
Sprite 0 bis 3 sollen in X-Richtung vergrößert werden, Sprite 4 bis 7 haben Normalgröße.
10 POKE 53277,15 :REM SPRITE 0-3 IN X-RICHTUNG VERGROESSERN (1+2+4+8=15)
LDA #%00001111 STA $D01D ; Sprite 0-3 in X-Richtung vergrößern / Sprite 4-7 normal
Farbgebung der Sprites[Bearbeiten | Quelltext bearbeiten]
Sprite-Nummer | Register / dez. / hex. | Funktion |
---|---|---|
0-7 | 28 / 53276 / $D01C | Farbmodus (0=einfarbig, 1=mehrfabig) |
0-7 | 37 / 53285 / $D025 | Mehrfarbenregister Farbe 0 (Bit-Paar = %01) |
0-7 | 38 / 53286 / $D026 | Mehrfarbenregister Farbe 1 (Bit-Paar = %11) |
0 | 39 / 53287 / $D027 | individuelle Farbe Sprite 0 |
1 | 40 / 53288 / $D028 | individuelle Farbe Sprite 1 |
2 | 41 / 53289 / $D029 | individuelle Farbe Sprite 2 |
3 | 42 / 53290 / $D02A | individuelle Farbe Sprite 3 |
4 | 43 / 53291 / $D02B | individuelle Farbe Sprite 4 |
5 | 44 / 53292 / $D02C | individuelle Farbe Sprite 5 |
6 | 45 / 53293 / $D02D | individuelle Farbe Sprite 6 |
7 | 46 / 53294 / $D02E | individuelle Farbe Sprite 7 |
Der Farbmodus wird in der Speicherstelle 53276 ($D01C) definiert. Für jedes Sprite ist ein Bit (0=Einfarbenmodus, 1=Mehrfarbenmodus) mit folgender Gewichtung vorgesehen:
Sprite-Nummer: | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Wertigkeit: | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
Einfarbenmodus[Bearbeiten | Quelltext bearbeiten]
Im Einfarbenmodus (HiRes-Modus) wird jeder Punkt eines Sprites in der gleichen Farbe angezeigt. Diese Farbe wird im entsprechenden Farbregister abgelegt. Der Wertebereich liegt zwischen 0 und 15. Der Rest des Sprites ist transparent.
Mehrfarbenmodus[Bearbeiten | Quelltext bearbeiten]
Im Mehrfarbenmodus (Multicolor-Modus) bekommen alle Sprites zwei zusätzliche gemeinsame Farben. Die horizontale Auflösung wird von 24 auf 12 halbiert, da bei der Sprite-Definition jeweils zwei Bits zusammengefasst werden. Jedes Pixel wird dadurch doppelt so breit. Es ergeben sich folgende vier Möglichkeiten:
Bit-Paar | Farbe |
---|---|
%00 | transparent |
%10 | Sprite-Farbenregister ($D027-$D02E) |
%01 | Mehrfarbenregister #0 ($D025) |
%11 | Mehrfarbenregister #1 ($D026) |
Beispiele[Bearbeiten | Quelltext bearbeiten]
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | (bei normalem Sprite) |---|---|---|---|---|---|---|---| Bit | 7 + 6 | 5 + 4 | 3 + 2 | 1 + 0 | (bei Multicolor-Sprite) |---|---|---|---|---|---|---|---| Bit-Wert |128|064|032|016|008|004|002|001| |---|---|---|---|---|---|---|---| 1. Beispiel | | | | | | | | | (Hintergrundfarbe), Wert 0 |---|---|---|---|---|---|---|---| 2. Beispiel | | X | | X | | X | | X | (Multicolor-Farbe 0), Wert 85 |---|---|---|---|---|---|---|---| 3. Beispiel | X | | X | | X | | X | | (Sprite-Farbe), Wert 170 |---|---|---|---|---|---|---|---| 4. Beispiel | X | X | X | X | X | X | X | X | (Multicolor-Farbe 1), Wert 255 |---|---|---|---|---|---|---|---| Diese Betrachtung gilt für einen Datenwert, der eine Linie darstellt. |---|---|---|---|---|---|---|---| 5. Beispiel | X | X | | X | | | X | | Datenwert 146 |---|---|---|---|---|---|---|---| Einmal alles gemischt, d.h. dreifarbige Linie
Sprite Anzeigeprioritäten[Bearbeiten | Quelltext bearbeiten]
Sprite/Sprite-Priorität[Bearbeiten | Quelltext bearbeiten]
Die Priorität zwischen den einzelnen Sprites ist festgelegt und kann nicht verändert werden. Sprite 0 hat die höchste, Sprite 1 die nächste und Sprite 7 entsprechend die niedrigste Priorität. Das bedeutet: Überlappen sich z.B. Sprite 1 und Sprite 3, so erscheint Sprite 1 vor Sprite 3. Dadurch kann ein dreidimensionaler Effekt erzeugt werden.
Anmerkung: Ein "Fenstereffekt" ist möglich, wenn ein Sprite mit höherer Priorität transparente Bereiche hat (Pixel=0 oder bei Multicolor %00). So scheinen Sprites mit niedrigerer Priorität durch (siehe Bild).
Sprite/Hintergrund-Priorität[Bearbeiten | Quelltext bearbeiten]
Sprite-Nummer | Registernummer / dez. / hex. | Funktion |
---|---|---|
0-7 | 27 / 53275 / $D01B | Hintergrund-Sprite-Priorität |
Das Prioritätsverhältnis zwischen Sprites und Bildschirmhintergrund wird durch das entsprechende Register in Adresse 53275 ($D01B) gesteuert. In diesem Register hat jedes Sprite ein Bit.
Ist das Bit 0, so hat das entsprechende Sprite eine höhere Priorität als der Bildschirmhintergrund. Das Sprite erscheint vor den Hintergrunddaten.
Ist das Bit 1, so hat der Hintergrund Priorität gegenüber dem Sprite. Das Sprite erscheint hinter den Hintergrunddaten. Genauer gesagt: Das Sprite erscheint hinter den Pixeln der Bits "1" für HiRes bzw. "10" und "11" für Multicolor, aber vor denen der Bits "0" bzw. "00" und "01".
In der Beispielanimation sieht man, wie das Sprite sich von rechts nach links vor dem blauen Hintergrund, aber hinter dem grünen Busch bewegt. Dabei scheint es im Bereich des Stammes teilweise durch, weil dessen Farbe Orange den Bits "01" zugeordnet ist und damit vom Sprite überdeckt wird.
Die einzelnen Bits dieses Registers haben folgende Gewichtung:
Sprite-Nummer: | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Wertigkeit: | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
Von diesem Register unabhängig hat der Bildschirmrahmen immer die höchste Priorität.
Achtung: Ein Spezialfall liegt vor, wenn Sprite A das Sprite B überdeckt, aber bei Sprite A das Hintergrund-Bit gesetzt ist, bei Sprite B jedoch nicht. In diesem Fall wird der Hintergrund angezeigt. Sprite B wird an der Stelle komplett ausgeblendet.
Beispiel[Bearbeiten | Quelltext bearbeiten]
Sprite 7 soll wieder vor den Hintergrunddaten erscheinen. Sprite 0 bis 6 sollen unverändert bleiben.
10 POKE 53275, PEEK(53275) AND 127 :REM BIT 7 IM PRIORITÄTSREGISTER LÖSCHEN
LDA $D01B ; Prioritätsregister lesen AND #%01111111 ; Bit7 löschen, Bit 0-6 bleiben unverändert STA $D01B ; Prioritätsregister schreiben
Sprites animieren[Bearbeiten | Quelltext bearbeiten]
Acht Einzelbilder und das animierte Ergebnis. |
- Um eine Sprite-Animation zu erstellen sind mindestens zwei aufeinander abgestimmte Bilder erforderlich.
- Die Sprite-Blöcke werden in der Abspielreihenfolge nacheinander im Speicher abgelegt.
Der Sprite-Datenzeiger wird solange hochgezählt, bis das Ende erreicht ist und wird dann wieder auf den Ursprungswert zurückgesetzt.
Kollisionserkennung[Bearbeiten | Quelltext bearbeiten]
Der VIC besitzt die Möglichkeit, Kollisionen zwischen Sprites untereinander oder zwischen Sprites und Vordergrundpixeln der Text- bzw. Bitmap-Grafik zu erkennen und ggf. einen Interrupt auszulösen. "Kollision" bedeutet in diesem Zusammenhang, dass ein oder mehrere gesetzte Pixel eines Sprites sich mit einem oder mehreren gesetzten Pixeln entweder eines anderen Sprites oder des Bildschirmhintergrundes überlappen.
Kollisionsregister[Bearbeiten | Quelltext bearbeiten]
Zwei VIC-Register können abgefragt werden, um zu erkennen, ob Sprites an einer Kollision beteiligt waren.
- $D01E (53278) zeigt Sprite-Sprite-Kollisionen. Für jedes Sprite, das mit einem anderen kollidierte, wird beim Bildaufbau sein Bit (also z.B. Bit 0 für Sprite 0) in diesem Register gesetzt. Alle anderen Sprites haben ein Bit mit dem Wert "0"
- $D01F (53279) zeigt Sprite-Hintergrund-Kollisionen. Für jedes Sprite, das mit einem gesetztem Pixel des Text- bzw. Grafik-Bildschirms - bei Multicolor stehen die Bitpaare 11 und 10 für gesetzte Pixel - kollidiert ist, wird beim Bildaufbau in diesem Register das zugehörige Bit gesetzt. Alle anderen Sprites haben hier ein Bit "0".
Die Bits bleiben gesetzt, bis das Register vom Prozessor gelesen und dabei automatisch gelöscht wird.
Wie bei allen anderen Registern mit einem Bit pro Sprite, ist Sprite 0 dem niederwertigsten Bit (Bit 0) und Sprite 7 dem höchstwertigsten Bit (Bit 7) zugeordnet.
Kollisions-Interrupt[Bearbeiten | Quelltext bearbeiten]
Das Interrupt-Request Register $D019 (53273) und das Interrupt-Enable Register $D01A (53274) sind für die Auslösung eines IRQs zuständig, wenn eine Kollision stattgefunden hat:
- Bit 2 (Wert 4) in beiden Registern ist für Sprite-Sprite Kollisionen zuständig
- Bit 1 (Wert 2) in beiden Registern ist für Sprite-Hintergrund Kollisionen zuständig
Software-Kollisionserkennung[Bearbeiten | Quelltext bearbeiten]
Die Hardware-Kollisionserkennung mit Hilfe der VIC-Register ist für einfache Fälle - z.B. wenn sich nur ein Spieler-Sprite bewegt und Kollisionen auslöst - gut einsetzbar. In komplexeren Situationen kommt diese Methode jedoch an ihre Grenzen. Sind z.B. mehrere Sprites gleichzeitig beteiligt, ist es schwierig festzustellen, welches Sprite mit welchem anderen kollidiert ist. Hier werden in der Spiele- oder Demo-Programmierung andere Methoden eingesetzt: die Software Kollisionserkennung [2] [3].
Beispiele[Bearbeiten | Quelltext bearbeiten]
Beispiel 1[Bearbeiten | Quelltext bearbeiten]
Stellt das Sprites 0 mit zufälliger Form in weißer Farbe dar.
POKE 2040,13: POKE 53248,255: POKE 53249, 100: POKE 53287,1
Beispiel 2[Bearbeiten | Quelltext bearbeiten]
Liest die Sprite-Kollisions-Bits aus.
PRINT PEEK (53278): PRINT PEEK (53279)
Beispiel 3[Bearbeiten | Quelltext bearbeiten]
Hier eine kleine Demonstration was mit 3 Sprites (Multicolor und einfach) möglich ist. Die REM-Zeilen brauchen nicht eingegeben zu werden. Sie dienen nur der Dokumentation des Programms. Außerdem passen diese leider nicht in der logischen Bildschirmzeile hinein! In der Variable V steckt der Anfangsspeicherbereich des VIC-II.
1 PRINT CHR$(147): V=53248: POKE V+33,0: REM Bildschirmbereinigung 2 FOR X=12800 TO 12927: POKE X,0: NEXT X: REM Speicherbereinigung für Sprite-Bereich 10 FOR X=12800 TO 12881: READ Y: POKE X,Y: NEXT X: REM Sprite-Generierung 11 POKE 2040,200: POKE 2041,201: POKE 2042,201: POKE V+21,7 12 POKE V+28,6: POKE V+37,15: POKE V+38,2: REM Multicolor für Sprite 1&2 13 POKE V+39,7: POKE V+40,8: POKE V+41,6: REM Sprite-Farbe Sprite 0&1&2 15 POKE V+23,7: POKE V+29,7: POKE V+16,1: REM Sprite-Eigenschaften Höhe, Breite, X-Position 16 POKE V+1,133: POKE V+2,170: POKE V+5,115: REM X-/Y-Positionen 19 REM Bewegung und Farbänderungen 20 FOR X=200 TO 1 STEP -1: POKE V,X: Z=Z+0.61: POKE V+3,Z 21 POKE V+4,(201-X)/2: NEXT X 22 POKE V+16,0: POKE V,255: M=PEEK(V+4) 23 FOR X=255 TO 170 STEP -1: POKE V,X: Z=Z+0.66: POKE V+3,Z 24 POKE V+4,M+(256-X)/1.2: NEXT X 25 FOR X=0 TO 5: FOR Y=1 TO 255: POKE V+37+X,Y: NEXT Y,X 26 POKE V+38,2: POKE V+39,7: POKE V+41,6 27 FOR Y=1 TO 65: POKE V+40,Y: POKE V+37,Y+10 28 FOR Z=0 TO 15: POKE V+39,Y: NEXT Z, Y 29 REM Warten, löschen von Sprite 0 und Ausblendung 30 FOR X=0 TO 3000: NEXT X 31 FOR X=0 TO 32: POKE 12832+X,0: POKE 12832-X,0 32 FOR Y=0 TO 100: NEXT Y,X: POKE V+21,0 39 REM SPRITE C64-WIKI.DE (einfarbig; Sprite 0) 40 DATA 239,81,85,139,81,20,137,81,28,137,81,89,137,213,89,142,85,93,138 41 DATA 95,85,138,91,85,238,91,85,0,0,0,0,0,0,0,0,0 42 DATA 0,199,0,0,231,0,0,164,0,0,180,0,0,151,0,0,180,0,0,164,0,0,231,0,0,199,0 44 REM Multicolor-Sprite Linie (Sprite 1&2) 45 DATA 0,255,255,255,170,85,170,170,85,170,85,170,85,85,170,85,255,255,255
Weiterführende Programmiertechniken[Bearbeiten | Quelltext bearbeiten]
Mit Raster-Techniken wie Sprite-Splitting und Sprite-Stretching stellt sich schon mal die Frage, was genau ein Sprite ist? Mit den genannten Techniken kann ein einzelnes Sprite in mehrere, mehr oder minder unabhängige Teile zerlegt werden, die ganz unterschiedliche Eigenschaften haben und vom Betrachter als eigenständige Objekte wahrgenommen werden. Aber kann man diese Einzelteile als eigenständige Sprites ansehen?
Man mag auf den ersten Blick geneigt sein, das zu verneinen, denn die Y-Koordinaten dieser Teile können nicht beliebig frei gewählt werden. Aber trifft das nicht auf jeden Sprite-Multiplexer so auch zu? Ist also nicht eher das, was der Betrachter des Bildschirms als Einheit wahrnimmt ein Sprite? Falls ja, so könnte man in jeder der ca. 300 Rasterzeilen zahlreiche Sprite-Punkte platzieren. Da mehr als ein Punkt pro Sprite dargestellt werden kann und sich diese scheinbar unabhängig von den anderen Punkten bewegen können, könnte man so auf ca. 10.000 darstellbare Sprites kommen.
Siehe auch[Bearbeiten | Quelltext bearbeiten]
- Movesprite - Programm zum Testen der Sprite-Positionierung (Quellcode: Sprite/movesprite).
Weblinks[Bearbeiten | Quelltext bearbeiten]
Wikipedia: Sprite (Computergrafik) |
Sprite Editor
- C64 Sprite Painter für Win32
- CSDb- Release Nr. 100657 SpritePad V1.8.1 für Windows von Subchrist Software
- CSDb- Release Nr. 132081 SpritePad V2.0 Beta 1 von Subchrist Software
- Sprite Machine 1985 Anirog Software/Scandomatic, D64 und Manual (PDF)
Programmierung
- Sprites in codebase64
- Sprites in Retro-Programming (Webarchiv)
- Programming sprites on the Commodore 64, a simple tutorial using BASIC V2 in Retro64
Quellen[Bearbeiten | Quelltext bearbeiten]
- ↑ Die Größe der Sprites hat sich beim Design des VIC-II aus Einschränkungen bezüglich der Speicherbandbreite ergeben, siehe Thema: Sprite-Größe auf Forum64.de
- ↑ Hybrid hardware software sprite collision detection
- ↑ Individual sprite 'boxes' for collision detection
Dieser Artikel wurde in die Liste der Lesenswerten Artikel aufgenommen. |