Hallo Besucher, der Thread wurde 3,6k mal aufgerufen und enthält 18 Antworten

letzter Beitrag von Lysosom am

Spriteposition auf Cursorposition umrechnen?

  • Huhu - gibt es da eine raffinierte Methode, festzustellen über welcher Cursorposition sich ein Sprite befindet?
    Ich möchte ein Zeichen im Textmodus per Mauszeiger auswählen.
    Dabei würde ich GERNE auf Kommazahlen verzichten.
    Gibt es da einen Trick?
    In ASM ist ok - ich werde es in C für den CC65 bzw. inline-ASM anwenden :o)
    Für jede Idee wäre ich dankbar :)
    Ciao,
    enthusi

  • Hi!


    Folgende Idee:


    Die X- und Y-Koordinate des Sprites hast Du ja zur Hand. Von der X-Koordinate ziehst Du den linken Rand und von der Y-Koordinate den oberen Rand ab. Hab jetzt aber nicht die genauen Randbreiten zur Hand. Den Wert den Du dann jeweils erhälst teilst Du durch 8 (da der Charset 8x8 Pixel breit ist) mit 3xLSR. Dann solltest Du die Charsetposition haben. Klar soweit?

  • Info:


    der sichtbare Bereich (also der nicht-Rand Bereich) fängt links bei Pixel 24 ($18 ) an, für die X-Koordinate und oben bei Pixel 50 ($32) für die Y-Koordinate bei 40 Spalten und 25 Zeilen


    Bei 38 Spalten und 24 Zeilen sinds 31 ($1F) für X und 54 ($36) für Y


    :D


  • Hallo,


    keine Ahnung, wie Du zu den Sprite-Koordinaten kommst, aber könnte man nicht alle 8 Pixel in y/x Richtung einen Zähler hochzählne, der entsprechend inkrementiert oder dekremnentiert wird, je nachdem, wohin sich das Sprite bewegt? Ist imho schneller, als das ganze auszurechnen ...


    Kommt natürlich drauf an, was genau Du machen willst.


    Ciao,
    Lysander

  • hallo, bischen spät, aber hier ein kleiner Lösungsvorschlag, vielleicht hilfts ja noch ;)


    ;umrechnen von Spriteposition auf Screen-Pointer
    ;Die X-Koordinate soll in XL und XH abgelegt sein (16bit), XH entspricht dabei dem Inhalt von v+16
    ;die Y-Koordinate kann direkt aus dem VIC-Register gelesen werden


    v=53248 ;VIC-Register
    scr =$f8 ;Zeropage-pointer auf Bildschirm-RAM
    lda v
    sta xl
    lda v+16
    sta xh


    lda xl ;linken Rand von x-koord. abziehen (16-bit-Subtraktion)
    sec
    sbc #24
    sta xl
    bcs bp1
    dec xh


    bp1 lsr xh ;dieser Wert (0-319) nun geteilt durch 8
    ror xl ;ergibt die Spalte
    lsr xl
    lsr xl
    sta scr
    lda #$04 ;HiByte des Pointers ist $04
    sta scr+1


    lda v+1 ;y-koord. lesen und -50
    sec ;(oberen Rand abziehen)
    sbc #50
    lsr a ;und /8
    lsr a ;ergibt die Zeile
    lsr a


    tay ;Zeile nach .Y
    beq done ;den bisherigen Pointer jetzt noch +40*Zeile
    loop lda scr
    clc
    adc #$28
    sta scr
    bcc bp2
    inc scr+1
    bp2 dey
    bne loop


    done lda #"x"
    sta (scr),y ;(.Y ist noch #0!), Ausgabe eines X an der BIldschirmposition
    rts


    xl .byte 0
    xh .byte 0

  • Ich buddel hier mal 'ne Leiche aus, aber falls jemand irgendwann - genau wie ich - bei der Suche nach dem Thema diesen Thread findet, so sollte doch erwähnt werden, dass der Code von hannez oben ein paar Fehler enthält.
    Nämlich: ein lsr zu wenig bei der X-Koordinate und vor allen Dingen darf unter dem ror xl nicht lsr xl stehen.
    SO ist es richtig:


    sprite_y, sprite_x und sprite_x+1 sollten bereits die Werte aus den VIC Registern enthalten.
    screenpos sollte ebenso wie in hannez Beispiel ein ZP-Pointer sein.
    vidmem0 ist bei mir eine feste 16-Bit Variable, die die Videomemoryadresse enthält.


    EDIT: achso, nicht über das von mir verwendete Offset wundern. Bei den sbc muss man ja die X/Y Koordinate wählen, die Koordinate Null entspricht. Das kann ja je nach Sprite variieren.

  • Aber warum kommt es bei Dir so auf Schnelligkeit bei so einer zeitunkritischen Routine an?


    Wenn Du verstärkt Demos codest, freust Du Dich irgendwann SEHR über Schnelligkeit. "Zeitunkritische" Sachen werden schnell kritisch, wenn man noch dies und das und jenes nebenbei im gleichen Frame erledigen will. Mir sind schnelle Sachen mittlerweile auch lieber als RAM-sparende.

  • Man könnte sich überlegen, ob man da nicht schneller eine Tabelle draus machen kann.
    Statt:


    wäre schneller (und vor allen Dingen immer konstant schnell):


    @edit

    Zitat

    Mir sind schnelle Sachen mittlerweile auch lieber als RAM-sparende.


    Besonders wichtig sind mir inzwischen Funktionen, die möglichst konstant schnell laufen. Damit erspart man sich die Sonderfälle wie "Jetzt läuft es mal langsamer, deshalb geht X oder Y in die Hose"

  • Edit: Es geht sogar völlig unmathematisch. Du schnapst Dir ein unbenutztes Sprite und läßt den VIC alle Berechnungen durchführen.


    Das ist "unmathematisch". Das ist simples "Rechnen" ;-) Das mit dem unbenutzen Sprite will ich mal überhört/überlesen haben... =P


    Sonst: Danke für die weiteren Vorschläge. Schnelligkeit ist nicht sooo wichtig. Hab noch reichlich Rasterzeit übrig.
    Früher oder später fliegt die Routine ohnehin wieder raus, weil ich den Pointer ja direkt mit der Spritebewegung verknüpfen kann.
    Momentan versuche ich allerdings noch so viele voneinander unabhängige Subroutinen wie irgendwie geht zu benutzen. Ist mein erster (ernsthafter) Versuch in Sachen Gamecoding und so ist es erstmal übersichtlicher, wenn irgendwas nicht läuft, wie gewünscht, heraus zu finden, wo der Fehler liegt.

  • Ich hab das meistens mit Spritekoordinaten als 8.3 Bit Fixedpointwerte gelöst, wobei der Vorkommateil dann so ziemlich direkt Reihe/Spalte entspricht. Je nachdem wie man die Werte für die Borderoffsets wählt und wann man die dazumixt kriegt man dann sogar noch ne einigermassen passable Rundung für lau. Die Bewegungsberechnungen werden allerdings geringfügig aufwendiger: