Hallo Besucher, der Thread wurde 7,8k mal aufgerufen und enthält 49 Antworten

letzter Beitrag von Gold Beaver am

Sprite von A nach B bewegen

  • Hallo Forum,


    Zuerst ein Gruß an alle, bin neu im Forum hier ...möchte euch aber schon mit 2 Fragen belästigen ^^
    Vorweg, bin mit C64-Assembler ziemlich am Anfang , hab mir erst ein Grundwissen angeeignet.


    1. Ich werkle grade mit einem einfarbigen Sprite über einem MC Bitmap rum und will es ganz simpel von links nach rechts laufen lassen.
    Soweit funktioniert das auch, nur muss ich ja bei 255 das MSBit einschalten damit mir das Sprite ganz zum Rand raus wandert, was mir auch gelungen ist. Nur flackert mir das Sprite beim umschalten des MSB (bei 255) läuft aber normal zum Rand. Das "Flackern" sieht so zirka aus als würde das Sprite kurz abgeschaltet und wieder eingeschaltet.
    Hier die Routine die das Sprite zum Rand raus bewegt.



    Diese Routine wird in einem Rasterinterrupt angesprungen.
    Was kann der Grund für das "Flackern" sein?


    2. Ist eine Frage um Klarheit zu schaffen.
    Obengenanntes Sprite is folgend aufgebaut: Die Spritedaten (nur Sprite 1(0)) liegen bei $5f00 , da die VIC-Bank 1 ($4000...) geschaltet ist. Nun musste ich ja den Spritepointer mit der richtigen Adresse füttern.
    Hier kommt nun der kuriose Teil: laut Berechnung wie vorgeschrieben wäre die $5f00 /$40=$17c , was ja nicht in ein Byte passt und meines Wissens ist der Spritepointer nur ein Byte breit. Als Juks hab ich einfach den Spritepointer mit $7c gefüttert und siehe da es ging !
    Könnte mir zu diesem Teil jemand eine "technische " Erklärung geben?


    Danke

  • hallo,


    zu 1) Einschalten musst du das Extrabit erst bei Werten >= 256. Da auf 255 prüfst und das INX schon vor der Prüfung aber nach der Spritepositionierung erfolgt, bist du ca. 2 Frames zu früh dran. :)


    zu 2) Der VIC kann immer nur 16K (= 1 VIC Bank) des gesamten Speichers sehen, welcher Bereich das ist wird durch $dd00/$dd02 festgelegt. Du hast dein Sprite in Bank1, die ab $4000 anfängt. Wenn du diese Anfangsadresse abziehst und dann durch 64 teilst passt das wieder :)

  • Hi,
    Danke schon mal gleich für die schnellen Antworten

    hallo,


    zu 1) Einschalten musst du das Extrabit erst bei Werten >= 256. Da auf 255 prüfst und das INX schon vor der Prüfung aber nach der Spritepositionierung erfolgt, bist du ca. 2 Frames zu früh dran. :)


    zu 2) Der VIC kann immer nur 16K (= 1 VIC Bank) des gesamten Speichers sehen, welcher Bereich das ist wird durch $dd00/$dd02 festgelegt. Du hast dein Sprite in Bank1, die ab $4000 anfängt. Wenn du diese Anfangsadresse abziehst und dann durch 64 teilst passt das wieder :)

    Zu 1: "Werte >=256" .. wie meinst das genau? ich dachte mit $ff hatte ich das, schon 255 aber mit der 0 mit gerechnet. könntest mir vielleicht Beispiel geben?


    Zu 2. Super, vielen Dank genau die Info fehlte mir , das mit Anfangsadresse abziehen konnte ich bis jetzt nirgends finden :).


    Lass die folgende Zeile einfach mal weg :

    Code
    1. cpx #$ff ; 255 erreicht?


    Edit: zu spät ...

    Wenn ich nur die Zeile weg lasse bleibt der gleiche Effekt :huh:

  • Setz doch $D010 mal testweise vor JSR Aufruf der Schleife (oder ganz am Programmanfang) auf #$01 und schmeiß aus der Schleife die 4 Zeilen raus:

    Code
    1. cpx #$ff ; 255 erreicht?
    2. bne exit ; wenn ja msb setzen und weiter
    3. lda #$01 ; Extra-Bit für Sprite 1 einschalten
    4. STA $D010
  • Hi TheRyk,


    Das bringt es leider nicht.. wenn ich das ExtraBit gleich setze erscheint ja das Sprite gleich schon am rechten Rand und läuft dort weiter.
    Und es sollte sich ja vom linken Rand zum rechten Bewegen.
    Meines wissens darf man das ExtraBit eben erst setzen wenn das sprite die maximale x Postion erreicht hat also Byte=255/56. Dann EB umschalten und weiter gehts. Nur ist a eben das dumme Flackern beim Umschalten sonst läuft es ja wie es soll.

  • Meines wissens darf man das ExtraBit eben erst setzen wenn das sprite die maximale x Postion erreicht hat also Byte=255/56. Dann EB umschalten und weiter gehts.

    Das Extra-Bit ist wirklich ein echtes, 9. Bit mit dem Zahlenwert 256. Dein Programm zählt 253,254,511,256,257,258... Lass echt mal das cpx#$ff weg, das sollte schon helfen.

  • Haubitze: Das mit der Y-Position werde ich sicherheitshalber auch noch testen.


    Hoogo: mit deiner Beschreibung wegen 9tem Bit und wie mein Programm zählt wird mir nun einiges klarer. Mir ist auch aufgefallen daß in dem Moment wie das Flackern eintritt manchmal ein Schatten des Sprites ganz links am Rand auftaucht, aber so kurz daß man gar nicht das ganze Sprite erkennen kann.


    Aber zurück zum Problem. Ich test das nochmal mit dem cpx #$ff weglassen, aber die Frage ist nun doch noch: wann soll ich nun das EBit aktivieren?
    Ich hatte ja eben die cpx #$ff-Abfrage Anfangs gemacht um zu setzen wann genau ich umschalten soll.


    Dann wäre noch nebenbei die folgende Sache: gegeben die Sache mit dem #$ff weglassen würde klappen. Nun möchte ich aber sobald das Sprite kurz vor dem Verlassen des Screens (rechts) also noch sichtbar ist, wieder retour läuf also Ping-Pong like. Das muss ich ja dann gezwungenerweise abfragen also im Sinn - Position x (nach 256) erreicht statt inx dann dex also rückwärts zählen.
    Wie könnte man so eine Routine anstellen bzw. wie wird das gezählt sobald man über 256 ist? die Abfrage für dann Rückwärts z.b $22 (von null aufwärts gerechnet)?. Und rückwärtsbezogen müsste ich das EBit dann ja wieder deaktvieren?.


    So eine in der Theorie einfache Ping-Pong Bewegung erweist sich ja in der Praktik dann als wahre Bastelei 8| :D



    Danke

  • ein beliebter Trick ist es lediglich die halbe Aufloesung in X zu benutzen.
    Also nicht 0-320 sondern 0-160.
    Erst wenn die neue sprite-X position gesetzt wird, verdoppelt man den Wert der ja vorher komplett in 8 bit gepasst hat.
    Nach dem ASL hast Du das 9. bit unmittelbar im carry und kann branchen, RORen oder sonstwas machen und somit d010 setzen.

  • ein beliebter Trick ist es lediglich die halbe Aufloesung in X zu benutzen.
    Also nicht 0-320 sondern 0-160.
    Erst wenn die neue sprite-X position gesetzt wird, verdoppelt man den Wert der ja vorher komplett in 8 bit gepasst hat.
    Nach dem ASL hast Du das 9. bit unmittelbar im carry und kann branchen, RORen oder sonstwas machen und somit d010 setzen.

    Hm.. ahso nebenbei als info, das Sprite ist auch X-Y Expanded.
    Enthusi (oder auch wer anders), könntest mir nen kleines stück code als Beispiel machen da würde ich das sicher schneller in den Kopp kriegen.
    Wäre echt dankbar dafür, wenns euch die Zeit und Lust erlaubt klarerweise :rolleyes:
    Nebenbei bastel ich klarerweis auch selbst weiter.


    Danke

  • Code
    1. lda xpos ;1byte nur
    2. asl
    3. sta $d000 ;xpos LSB
    4. rol $d010 ;von links das 'ueberlauf' carry in xpos MSB schieben.


    SO geht das natuerlich nur fuer das erste Sprite.
    Bei mehreren, faengst Du einfach mit den hoechsten an.

  • enthusi
    Danke für dein Stück code, könntest du mir einen Tip geben wie ich den jetzt z.b in meinem Quellcode einsetzen kann? muss ich eventuell die Position 160 abfragen? :|


    Endurion: danke für dein Link (is ja nen cooles Project) den Joystick-Sprite Teil guck ich mir auch gleich an :rolleyes:

  • na das kommt da in deinen code wo du den X wert holst den das sprite haben soll und ihn in d000 schreibst.


    wenn deine werte aus ner tabelle kommen musst du die so abändern das jeder wert nur nach halb so groß ist (unnötiger weise könntes du nach dem laden der wertde LSR machen) wenn du das über increase machs dann hast du nur 160 schritte und keien 320.


    Code
    1. movesprite:
    2. lda spritex ;1byte nur
    3. asl
    4. sta $d000 ;xpos LSB
    5. rol $d010 ;von links das 'ueberlauf' carry in xpos MSB schieben.
    6. rts


    kein vergleich mit $ff oder so,
    schau dir an was die befehle asl und rol machen da verstehs du was das soll, in grunde nimmt man x2 und benuzt den carry


    http://unusedino.de/ec64/technical/aay/c64/bmain.htm

  • Jups , danke Green .. das war die Lösung :zustimm:


    Im Moment mach ich das über increase also keine Tabelle, der Test sollte ja nur von links nach rechst gehn.
    Also die kurze Routine sieht jetzt so aus:


    Code
    1. movesprite:
    2. lda spritex ;1byte nur
    3. asl
    4. sta $d000 ;xpos LSB
    5. rol $d010 ;von links das 'ueberlauf' carry in xpos MSB schieben.
    6. inc spritex ; erhöhen
    7. rts



    Die Variante von Endurion sein Game raus funkioniert auch rund (hab sie für mich ein bisschen verändert, war auf mehrere Sprites ausgelegt) , also hab ich schon 2 varianten :D




    Nun muss ich mir nur noch ne Schleife ausdenken für den Ping-Pong effekt, also von links nach rechst am rechten Rand wieder zurück und wieder von vorne.


    Danke an alle bis hier her schon mal herzlich :D


    Gruß
    sidguy

  • Nun muss ich mir nur noch ne Schleife ausdenken für den Ping-Pong
    effekt, also von links nach rechst am rechten Rand wieder zurück und
    wieder von vorne.


    Hmm.., ich progge in Boss-Basic .
    Ich habe den PiPO-Effekt erzeugt in dem ich am rechten und linken Rand jeweils von oben nach unten Buchstaben gesetzt habe.
    Wenn das Sprite eine collision (Colliüberprüfung einfach für den Hintergrund setzen ) hatte wurde die Richtung einfach umgedreht.


    Kannst auch einen Buchstaben nehmen oder noch ein anderes Sprite welches du als Schläger hoch und runter bewegen kannst und dann die Colliprüfung, damit es zurück marschiert...also tausend Möglichkeiten.
    Dann den Marschwinkel ein bisschen ändern damit es auch mal schräg abprallen tut...


    gruss

  • @Plus4Fan... jo wär auch was aber im Moment wollte ich nur Sprite hin und her über nem MC Bitmap machen. ;).. mit Collis in Assembler muss ich mich erst noch richtig befassen.



    Green .. noch nen Gedanken zur Routine vorhin: mit asl auf die X-Posi bedeutet auch daß das Sprite sich schneller bewegt nehm ich an?
    Plus wegen Pipo effekt , das Sprite soll ja nicht bei Posi 0 anfangen links sondern bei $18 also noch sichtbar sein an den Rändern wenn es umkehrt. Mal sehn was ich hinbekomm , jetzt muss ma mit was den Magen füttern der knurrt schon dolle. :D