Ich hab mir das Register mal genauer angeschaut:
Erstmal hab ich eine Website Konsultiert, die den VIC recht genau beschreibt: (
http://www.minet.uni-jena.de/~andreasg/c64/c64_vic_html.htm).
Dort steht:
- $d01e Sprite-Sprite-Collision
if sprites collided, here you see which sprites that were;
the corresponding bits gets high(1);
after reading you have to clear the bits because they don't clear themself;
- $d01f Sprite-Background-Collision
if sprites collide with a backgroundsign the corresponding bits get high;
also like in $d01e you've to clear bit's after reading the;
Nun hab ich ein kleines Testprogramm geschrieben.
Das ergebnis ist, das nach dem auslesen des Registers, es schon gelöscht wird. Warum man es selbst nochmal tun soll, weiß ich nicht. Mein Testprogram nutzte 3 Sprites, und die Testumgebung war der Vice Emulator. In der Schnelle hab ich es nicht auf einem echten 64'er getestet. Gab es vielleicht mal einen VIC II der etwas anders bei den Kollisionsregistern reagierte, oder warum sollte man diesen selbst löschen? Insofern stimme ich Dr. Creep zu.
>Es können nie 3 Sprites geichzeitig kollidieren,
>zuerst treffen immer 2 aufeinander, da ein Programm
>sequenziell abgearbeitet wird.
>Man muß natürlich auf's Timing bei der Abfrage achten
>(i.d.R. wird man das per Interrupt steuern).
Der Theorie nach stimmt es, bringt aber einige Probleme mit sich. Es hängt auch etwas von der Codestruktur ab.
1. Bewege ich einen Sprite, und schaue gleich ob er kollidiert, dann mag das gehen.
2. Bewege ich erst alle Sprites, und prüfe danach alle Kollisionen, wirds nicht mehr klappen. Welcher Sprite nun mit welchem? *beiß in Tastatur* Das Programm wird auch sequenziell abgearbeitet, aber es klappt nicht.
Auch erste Methode kann hinterlistig sein.
Gehen wir mal davon aus, wir haben ein Hauptprogramm das sequenziell abgearbeitet wird. Unser Programm befindet sich gerade auf der Rasterzeile #$70. Dort bewegt es Sprite 1 auf Y Position #$c0. Es prüft, ob eine Kollision mit Sprite 2 stattgefunden hat, welches auch bei #$c0 liegt. Das Programm ist jetzt vielleicht in Rasterzeile #$72, durch den Rechenzeitverbrauch, angelangt. Falls man nun prüft, ob eine Kollision stattgefunden hat, bekommt man ein "NEIN" zurück und man verschiebt Sprite 1. Doch warum ist das so? Der VIC setzt die Bits des Kollisionsregisters immer erst dann, wenn er dieses Sprite gerade zeichnet. Das geschieht also erst ab Rasterzeile #$c0. Erst jetzt wird die Kollision ins Register geschrieben. Beim nächsten Framedurchlauf würden wir dann den Wert erhalten, aber zu spät, da wir die Sprites schon ineinander verschoben haben. Wenn man das ganze nun noch mit Sprite 2 & 3 macht, ist der wahnsinn völlig komplett. So passiert es auch bei sequenzieller Abarbeitung, das 3 Sprites gleichzeitig kollidieren können, ohne das das Hauptprogramm es über die Kollisionsregister gleich mitbekommt.
Richtig kompliziert wirds dann, wenn man Spritemultiplexer nutzt. Ich fürchte, das alles was man versucht komplizierter wird, als durch den Vergleich von Koordinaten. Es ist auch besser eine Kollision vorher zu wissen (vor der Speicherung in die eigentlich X & Y Koordinate) und danach die Bewegung des Sprites zu koordinieren. Sicher hängt es auch stark davon ab, was man machen möchte.
Im Grunde wollte ich nur damit sagen, das du nach einer Verschiebung den Kollisionswert nicht sofort bekommst, sondern verzögert. Die Verzögerung ist um so größer, je weiter die Rasterzeilen-Position des Kollisionscodes von der Rasterzeilen-Position des Sprites entfernt ist. Das ist eben das Hauptproblem, welches man beim Vergleich mit Koordinaten nicht hat.
Wenn ich Unrecht habe, lass ich mich gerne belehren. Man lernt nie aus!
Gruss,
BGU / PTV