Hallo Besucher, der Thread wurde 9,1k mal aufgerufen und enthält 43 Antworten

letzter Beitrag von Acorn am

Sprite Hintergrund Kollision

  • Da ja eine Sprite-Hintergrundkollision mir nur den Wert zurückgibt dass eine Kollision stattgefunden hat aber nicht mit welchen Zeichen, wollte ich fragen wie ihr das so löst.
    Meine Idee wäre es die Sprite Koordinaten mit einer Tabelle zu vergleichen um dann an gegebener Stelle die Hintergrund Kollision abzuschalten und dann eine dementsprende Aktion ausführen.
    Wäre das so der richtige Ansatz?

  • Sprite Position ist in Pixeln, Chars jeweils 8 pixel.
    Also teilt man durch 8.
    Die Spritekoirdinaten bei Zeichen 0,0 sind aber nicht 0,0. Daher das offset.
    Für y nimmt man eine Tabelle die Zeilenanfänge enthält oder rechnet 40*y.
    Dazu addiert man x und hat die Position bzw Adresse des Chars beim Sprite.
    Über den Offset bestimmt man auch, wo im Sprite man sein möchte. In Turrican werden zB drei Chars unter den Füßen ständig überprüft.

  • soweit komme ich noch

    wie muss ich das weiter verfahren?

  • Lookup = Nachschlagen
    Lookup-Table = Eine Tabelle zum schnellen Nachschlagen von Werten, damit diese während des Spiels nicht umständlich berechnet werden müssen.


    In der Tabelle speichert man vorberechnete Werte, um Programme zu beschleunigen. Besonders in Graphikroutinen z. B. bei der Adreßberechnung sind solche Tabellen sehr hilfreich, zumal sie - wie im vorliegenden Fall - auch gar nicht so viel Platz einnehmen.


    Je nach Assembler läßt sich die Tabelle für die Bildschirmadressen nach folgendem Schema anlegen:

    Achtung: Die Syntax variiert hierbei von Assembler zu Assembler. Einige Assembler erlauben es auch, Tabellen mit einer FOR-Schleife zu erzeugen. Dazu müßtest Du Dir mal passende Codebeispiele für Deinen Assembler ansehen.


    Es existieren nun zwei Tabellen für den Bildschirm: die eine enthält nur den niederwertigen (low) Anteil der Adresse, die andere nur den höherwertigen (high). Diese Spaltung in low und high hat den Vorteil, daß man die Tabellen sehr einfach mit einem Indexregister indizieren kann, um die passende Adresse zu bekommen:

    Wenn Du ganz schnellen Code haben willst, kannst Du auch Tabellen erzeugen für jede Sprite Y-Position, ohne vorher Y durch 8 zu teilen, d. h. die Tabelle wird entsprechend 8 mal so groß, da jeder Eintrag (von 0..24) 8 mal nacheinander geschrieben wird. Dadurch spart man sich dann das umständliche dreifache LSR. Außerdem läßt sich noch mehr Code sparen, indem man den festen Offset nicht mehr von Y abzieht, sondern einfach die Anfangsadresse der Tabellen im Code um diesen festen Wert reduziert:

    Code
    1. ldy ykoo
    2. lda bildschirm_low - offset, y
    3. sta zp_zeiger
    4. lda bildschirm_high - offset, y
    5. sta zp_zeiger + 1

    Dies wäre die schnellste Methode, um die Adresse einer Zeile zu berechnen. Da es eher nicht wahrscheinlich ist, daß Dein Programm den ganzen Speicher des C64 belegt, kannst Du Dir ruhig den komfortablen Luxus erlauben, solch große Tabellen anzulegen.


    Nebenbei: Man kann diese Tabellen auch vom Programm zu Beginn einmalig berechnen lassen und muß sie damit nicht in den Programmcode einfügen, oder man läßt sie zusammen mit dem restlichen Programm mit dem Exomizer packen.


    Eine Sache noch zu den X-Koordinaten:
    Die Sprite-X-Koordinaten benötigen auch immer ein Highbyte, selbst wenn dieses nur die Werte 0 und 1 annehmen kann. Bei der Subtraktion des X-Offsets (24) müßte man also so etwas schreiben wie:

    Und zum Schluß noch der Hinweis, daß man unbedingt die Sonderfälle berücksichtigen muß, bei denen das Sprite teilweise außerhalb des Bildschirms ist. Entweder vermeidet man dies generell, oder die Berechnungen werden ein wenig komplizierter.

  • >> und << sind bitweises rotieren = /2 und *2.
    >> 8 ist also ein /256
    das & ist ein bitweises UND.
    Das gibt zusammen als das MSB eines 16 bit words aus.
    Viele Assembler nehmen zB auch #>adresse und deuten das '>' als MSB.
    (MSB hier: most significant byte)

  • Hab mal was dank eurer Hilfe sowas zusammengebastelt und funktioniert auch soweit:

    ist das so der richtige Weg?

  • Cool, dann bin ich also auf den richtigen Weg.
    Bin jetzt sogar so weit, dass ich das Zeichen abfragen kann mit dem das Sprite kollidiert :thumbsup:
    Nur vertehe ich noch nicht das mit der x-Position MSB.
    Wozu brauche ich das, wenn es doch funktioniert?
    Ach ja, danke für eure Gedult :love:

  • Wozu brauche ich das, wenn es doch funktioniert?

    Es funktioniert nur, solange Du die X-Position der Sprites auf 0 .. 255 beschränkst. Der Bildschirm hat in X-Richtung jedoch mehr als 256 Pixel. Um Dein Sprite auch am rechten Rand anzeigen lassen zu können, brauchst Du für einen kompletten X-Wert noch ein 9. Bit. Damit kann man von 0 .. 511 zählen, was für den C64 ausreicht. Dieses 9. Bit speichert man in einem zusätzlichen Byte des X-Wertes. Anders als für Y nimmt man für den X-Wert also stets zwei Bytes. MSB ist hierbei die Abkürzung für "Most Significant Bit" oder einfacher gesagt "das höchste Bit". Wenn der vollständige X-Wert aus 9 Bits besteht, werden die ersten 8 in das erste Byte der Koordinatenvariable gespeichert (Low Wert) und das MSB (das 9. Bit) dann in ein weiteres Byte (High Wert) - auch wenn es vielleicht etwas verschwenderisch erscheint, für ein Bit gleich ein ganzes Byte im Speicher zu verbrauchen.
    Nebenbei: Guck Dir mal die Register des VIC an. Dort findest Du bei $d000, $d002, $d004 jeweils die ersten 8 Bit des Sprites. Bei $d010 jedoch liegen die gesammelten MSBs der Sprites.

  • Nächstes Problem :D :


    Code
    1. title
    2. !media "title.charscreen",charcolor
    3. level
    4. !media "level1.charscreen",charcolor
    5. sprites
    6. !media "testsprite.spr",sprite

    Zuerst hatte ich nur Die Sprites nach $2000 kopiert dann den "level1" nach $0400.Ok, so weit so gut und es funktionierte tadellos.
    Nur wenn ich jetzt die Zeile mit "title" hinzufügen, dann ist mein Sprite "zerschossen"
    ich habe den Verdacht, dass damit meine Sprites überschrieben werden, zumindest ein Teil davon.