Beiträge von flashback im Thema „Sprite-Animation / Farbwechsel“

    Es läuft schon, nach der erwähnten Änderung, aber es läuft viel zu schnell ab!

    Bei $6200 scheint der IRQ für die Musik und das Blinken zu liegen.
    Dort wird anscheinend (nach der Musik) gleich 4x zur Blink-Routine gesprungen.

    Code
    .C:620d  20 03 10    JSR $1003
    .C:6210  20 00 82    JSR $8200
    .C:6213  20 00 82    JSR $8200
    .C:6216  20 00 82    JSR $8200
    .C:6219  20 00 82    JSR $8200


    Damit wird diese also bei PAL 200x in der Sekunde aufgerufen. Selbst wenn sie nur 1x aufgerufen wird, würde das Blinken in ca. 0,25 Sek durchlaufen.

    Verdammt, du hast recht, ich hatte vollkommen vergessen, daß ich die Routine pro IRQ viermal aufrufe, damit die Animation der Sprites schneller abläuft. Die Blink-Routine habe ich erst danach hinzugefügt und nicht mehr an den Aufruf gedacht. Danke, darauf wäre ich nie gekommen.


    Außerdem gibt es noch ein zweites Problem:
    Hier setzt du spr_ColorPointers zwar auf 0...

    Code
    lda #$00 // Sonst
                        sta spr_ColorPointers,y // Color-Pointer und
                        sta spr_FlashActive,y // Blink-Flag auf 0 setzen

    ...läufst dann aber direkt weiter in den folgenden Abschnitt...

    Code
    spr_SetColor:
                        sta $d027,y // Farbe setzen
                        inx // Color-Pointer +1
                        txa // X -> A
                        sta spr_ColorPointers,y // Neuen Color-Pointer speichern


    ...hier wird spr_ColorPointers dann auf einen ungültigen Wert gesetzt! Da X immer noch aufs Tabellenende zeigt und nun auch noch um 1 erhöht wird.

    Stimmt, der nachfolgende Code wird ja trotzdem ausgeführt... habe das jetzt mal wie folgt angepaßt.

    Jedenfalls funktioniert es jetzt erstmal, wie es soll. Das Timing zwischen Bewegung und Blinkfrequenz anzupassen, ist dann der nächste Schritt.

    Kiri, ich sehe gerade deine Signatur, bist du derjenige, der für die Seite retro-programming.de verantwortlich ist? Falls ja, möchte ich dir an dieser Stelle ein großes Lob aussprechen. Die Seite hat mir beim Einstieg in Assembler sehr geholfen.
    :thumbsup:


    Dann ist der Test unnötig. Wenn der untere Rand erreicht wurde => Flashen. Ob das vorher auch schon der Fall war, ist an der Stelle egal.

    Ganz so einfach ist es leider nicht. Wenn der untere Rand erreicht wurde, soll nur angefangen werden zu blinken. Aber während die Sprites blinken, bewegen sie sich ja auch wieder nach oben, dann würde der "Blinkvorgang" in dem Moment abbrechen, wenn die Koordinaten nicht mehr stimmen. Deshalb muß ich ja diesen Umweg über die Flags gehen.

    Ich denke, Squidward und Mac Bacon haben schon recht, das Problem ist deine Y-Abfrage.

    Vertausche hier mal die Abfragen...

    Code
    //***************** Blink-Routine
                        cmp spr_BorderBottom // Unterer Rand erreicht?
                        bne spr_NoFlashing // Nein? Dann Sprung
    
    
                        lda spr_FlashActive,y // Blink-Flag laden
                        bne spr_DoFlashing // 0? Nein? Dann Sprung


    Sonst greift dein spr_FlashActive-Pointer nur in dem Moment, wenn Y = unterer Rand ist.
    Achte aber darauf, dass du den Akku für das cmp nicht veränderst!

    Code
    //***************** Blink-Routine
                        ldx spr_FlashActive,y // Blink-Flag laden
                        bne spr_DoFlashing // 0? Nein? Dann Sprung
    
    
                        cmp spr_BorderBottom // Unterer Rand erreicht?
                        bne spr_NoFlashing // Nein? Dann Sprung

    Okay, nach dem Vertauschen der beiden Blöcke blinken die Sprites tatsächlich regelmäßig bei jedem Ereichen des unteren Rands, allerdings tritt jetzt das oben beschriebene Problem auf, daß das Blinken aufhört, sobald die Y-Koordinate nicht mehr dem unteren Rand entspricht, ist ja auch logisch.

    Hmm, damit es so funktioniert, wie es soll, muss jetzt die Anzahl der passenden Y-Koordinaten in der Tabelle mit der Anzahl der Blink-Farben übereinstimmen, dann geht's. Aber wie schon gesagt, eigentlich sollen die Sprites solange weiterblinken, bis alle Farben aus der Farbtabelle gelesen wurden und nicht nur dann, wenn die Koordinaten mit dem unteren Rand übereinstimmen.

    Erstmal vielen Dank für die Antworten.


    Hab nur kurz raufgeschaut, aber überspringst du deine Flash-Routine nicht immer - ausser wenn die Position *genau* "Sprite_BorderBottom" entspricht?

    Code
    cmp spr_BorderBottom // Unterer Rand erreicht?
    *bne* spr_NoFlashing // Nein? Dann Sprung


    Bei Zeile 14 vielleicht mal bmi statt bne nehmen..?

    Hmm, eigentlich sollte das nicht so sein, deshalb ja die Flags. Falls die Y-Position = spr_BorderBottom ist, dann soll erstmal geguckt werden, ob die Flash-Routine gerade aktiv ist:

    Code
    lda spr_FlashActive,y
    bne spr_DoFlashing

    Falls ja, direkt aufrufen. Falls nicht, Flash-Flag für das Sprite auf 1 setzen, der untere Rand wurde ja erreicht:

    Code
    lda #$01
    sta spr_FlashActive,y


    Ich glaub', da stimmt was nicht:

    Code
    lda spr_FlashActive,y // Blink-Flag laden
    bne spr_DoFlashing // 0? Nein? Dann Sprung
    
    
    lda #$01 // Sonst Blink-Flag
    sta spr_FlashActive,y // auf 1 setzen
    
    
    lda spr_FlashActive,y // Blink-Flag laden
    beq spr_NoFlashing // 0? Dann Sprung


    Da wird von Bitte melde dich an, um diesen Link zu sehen. auf Bitte melde dich an, um diesen Link zu sehen. gesetzt, dann wieder geladen und auf Bitte melde dich an, um diesen Link zu sehen. verglichen?

    Stimmt, das ist irgendwie doppelt gemoppelt, ich habe diese beiden Zeilen jetzt mal rausgenommen, der Vergleich ist an der Stelle ja unnötig. Aber am Verhalten hat sich leider auch nichts geändert.

    Code
    lda spr_FlashActive,y
    beq spr_NoFlashing

    Ich habe mir die Animation gerade mal länger angesehen und festgestellt, daß das Blinken nur bei jedem 12. Mal (ca. nach 13 Sekunden) ausgeführt wird. Also scheinen die Flags doch korrekt zurückgesetzt zu werden. Seltsam... ich hänge mal das D64-Image an.

    So, ich habe mal versucht, alles in einer Schleife zu lösen, Dank des Tipps mit der Offset-Tabelle klappt das schon ganz gut.

    Das einzige Problem ist, daß das Blinken, was an einer bestimmten Y-Koordinate ausgelöst werden soll, nur einmal ausgeführt wird, danach nicht mehr. Irgendwo wird eine Flag wohl nicht korrekt zurückgesetzt, aber ich kann nichts finden?

    Hier mal die Schleife:


    Also wenn jedes Sprite "seinen eigenen Pointer auf die Farbtabelle" braucht, dann leg diese acht Pointer in eine Tabelle und ruf sämtliche Sprite-Routinen mit dem entsprechenden Offset in Y auf.

    Die Pointer für jedes Sprite sind aber nicht fest, die ändern sich ja mit jedem Frame:

    Das heißt, Sprite 0 ist meinetwegen gerade bei Farbe $0f, Sprite 1 bei $0b usw.

    Ein weiteres Problem ist (zumindest für mich ;) die Tatsache, daß die Y-Koordinaten in der Schleife in Zweierschritten gesetzt werden ($d001, $d003, ...), die Farbwerte aber in Einerschritten ($d027, $d028, ...). Brauche ich dann nicht zwei Schelifenzähler, um das abzufragen?

    Und wie genau fange ich das am besten an? Die Schleife zum Durchlaufen der Y-Koordinaten ist kein Problem, aber der Sprung zu "ColorRefresh" würde ja dann die Schleife unterbrechen. Also würde meinetwegen Sprite 0 blinken, die Abfrage für Sprites 1-7 würden dann aber gar nicht mehr greifen. Oder mache ich da einen Denkfehler?

    Moin,

    ich brauche mal einen Denkanstoß für meine Routinen:

    Routine 1: Animation. Hier werden nur die Koordinaten aus einer Tabelle gelesen und für alle Sprites gesetzt.

    Routine 2: Farbwechsel. Die Sprites sollen blinken, wenn sie eine bestimmte Y-Koordinate (Label "spr_BorderBottom") erreicht haben. Bisher ist das für jedes Sprite einzeln realisiert:

    Nun meine Frage: Kann man das nicht irgendwie in einer Schleife erledigen? Das Problem ist, daß jedes Sprite seinen eigenen Pointer auf die Farbtabelle braucht, sonst blinken ja alle im gleichen Rhythmus. So wie es jetzt ist, funktioniert es zwar, ist aber nicht schön programmiert...