Project J - Wir schreiben ein C64 Spiel in mehreren Schritten

  • Und wir fixen die letzten Bugs. Der Score wurde nach einem Game Over nicht sauber zurückgesetzt, und die Musik quält sich während des Speicherns weiter.


    Und falls es doch noch jemand nicht wußte, die ausgebaute Finalversion ist als Guns'n'Ghosts bei Psytronik und RGCD erhältlich!






    Damit ist dieser Exkurs beendet.


    Viel Spaß und vielen Dank für Ihre Aufmerksamkeit!


  • Hallo,
    hat schon mal wer was bei Psytronik bestellt das per Post geschickt werden musste?
    Ich habe mir heute 2 Sachen geordert. Einmal Guns 'n' Ghosts als Digital Download.
    Aber dann noch Assembloids als Tape Version. Ich habe per Paypal bezahlt und danach wurde erst die Auswahl der Versandmöglichkeiten
    und die Kosten dafür angezeigt. Ich habe also bis jetzt nur die Programme bezahlt, aber noch nicht den Versand. Das lief irgendwie in der
    falschen Reihenfolge ab.

  • Ich habe dort schon mehrfach bestellt, ja. Allerdings habe ich mir ein Kundenkonto eröffnet. Du bist wohl direkt über den Paypal Button gegangen? Keine Ahnung warum da nicht vorher Porto kalkuliert wird. Mit Kundenkonto kommt man gar nicht zu Paypal ohne vorher Porto auszuwählen.
    Evtl. Kenz mal anschreiben. Oder warten bis er sich meldet. Das kann aber ein paar Tage dauern.

  • Hallo Endurion!


    Erst mal vielen herzlichen Dank für die viele Arbeit und alles hier reinzustellen!
    :-)


    Ich bin grad dabei mir Spieleprogrammierung auf dem C64 in Assembler beizubringen
    und arbeite deswegen genau solche Quellcodes durch. Heute (und auch gestern schon)
    stecke ich schon den ganzen Tag im Step 3:



    In diesem Step 3 hast Du die Steuerung des Sprites mit dem Joystick hinzugefügt und
    ich versuche alles zu verstehen.
    Jetzt scheint es mir, nach 2 Tagen grübeln und ärgern dass ich nicht alles verstehe, dass
    Du vielleicht Code-Schnipsel von anderen Spielen eingebaut hast, die zum Teil noch
    Zeilen enthalten, die in diesem Schritt überhaupt nicht oder erst viel später gebraucht
    werden und die überhaupt nicht erklärt werden oder gebraucht werden. Kann das sein?


    Hier konkret, bei einer Bewegung nach links sowie dem Update des 9'ten Bits für den
    Überlauf der X-Koordinate (255):



    Konkret machst Du unter .NoChangeInExtendedFlag ein TXA, ein ASL und ein TAY, das hier überhaupt nicht
    gebraucht wird (hab's auskommentiert, läuft auch einwandfrei ohne!).
    Mit Step 4 hat das also sicher nichts zu tun! Oder?
    Ich muss sagen, solche Dinge verwirren mich EXTREM wenn ich versuche die blutigen Anfänge zu lernen!
    Naja, das nur als Feedback von einem blutigen Anfänger.
    Ich bin natürlich dankbar dass Du den Code überhaupt veröffentlichst, aber für mich als Anfäger
    sind solche Dinge im Code die darin nichts verloren haben aber sehr den Anschein machen
    extrem verwirrend... - Das nur als Tipp, falls Du mit diesen 100 Steps mal ein Buch für
    Anfänger schreiben möchtest, was natürlich super wäre... :-)


    LG,
    Markie

  • Ändere Deinen Code mal von Sprite 0 zu Sprite 1 und Du wirst sehen, wozu der auskommentierte Bereich gut ist. ;)


    Die Designer des VIC haben die Register für die Sprite-Koordinaten leider nicht so angeordnet:

    Code
    1. x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7


    sondern so:

    Code
    1. x0, y0, x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6, x7, y7


    Man muss also beim Zugriff auf diese Register den Index verdoppeln; genau das tut die Codesequenz TXA:ASL:TAY.
    Wenn man nur Sprite 0 benutzt, macht das natürlich keinen Unterschied, denn zwei mal Null bleibt Null.

  • Hallo Mac Bacon!


    Hey danke für die Erklärung! :):)


    Und nochmehr danke für den ACME!! :D^^


    Zum Index der verdoppelt wird:
    Wieso den Index verdoppeln? Du meinst doch zwei mal inkrementieren, oder?
    Das ist ja gar nicht das selbe wie Verdoppeln!!!
    --> +2 ist nicht gleich * 2!
    --> 0, 2, 4, 6, 8 ist nicht gleich 1, 2, 4, 8, 16
    Und wieso überhaupt WÄHREND der Spritebewegung plötzlich die Spritenummer ändern???
    Das ist doch völlig hirnrissig! - Sorry, ich hab eben völlig Bahnhof dazu...
    Dass da der Index verdoppelt wird, das hab ich mir nach 2 Tagen auch mühsam zusammengebröselt.
    Nur: Das macht für mich keinen Sinn!
    Ja, Du hast recht, die X und Y Koordinaten sind paarweise im Speicher abgelegt.
    Das heisst aber eben nicht, dass der Index verdoppelt werden muss um auf den nächsten
    Wert zuzugreifen. Er muss einfach um + 2 anstatt um +1 inkrementiert werden für
    das nächste Sprite, bzw. dessen X Koordinate. Oder hab ich da was wichtiges verpasst
    oder verwechselt? Wohl schon, nur was???
    Gemäss obigem Quellcode ist es doch so, dass die Sprite-Nummer als Index im X-Register liegt.
    Also 0, 1, 2, 3, etc.


    Ich kleb mal den ganzen Quellcode rein:



    Wenn man diesen Index jetzt mit Bitshift (ASL) verdoppelt, dann bleibt ja Sprite 0
    noch immer Sprite 0: %00000000 -> %00000000
    Sprite 1 wird zu Sprite 2: %00000001 -> %00000010, ok,
    aber Sprite 2 zu Sprite 4: %00000010 -> %00000100,
    und Sprite 3 zu Sprite 6, 4 zu 8 und Sprite 5 zu 10, usw.
    Doch warum sollte man überhaupt wärend der Bewegung plötzlich die Sprite
    Nummer ändern wollen? Das ist doch völlig widersinnig!
    - Abgesehen davon, dass es hier weit und breit nur ein Sprite gibt, aber das
    nebenbei, vielleicht ist der Code ja später nützlich, nur das verstehe ich eben
    noch überhaupt nicht!


    Liebe Grüsse und sorry wenn ich da ein wenig schwer von Begriff bin... :/
    Markie

  • Zum Index der verdoppelt wird:
    Wieso den Index verdoppeln?

    Weil die Positionsregister im VIC so angeordnet sind, dass man "Register von Sprite N" bei der Adresse "Basis + 2 * N" findet.
    Beispiel:
    Die logischen Spritenummern gehen von 0 bis 7. Wir wählen das Sprite mit der Nummer "N", dann gilt:
    Der Spritezeiger von Sprite N liegt bei SCREEN_BASE + 1016 + N.
    Das Farbregister von Sprite N liegt bei $d027 + N.
    In Endurions Beispielprogramm werden die Koordinaten in zwei separaten Tabellen abgelegt,
    der X-Wert von Sprite N liegt bei SPRITE_POS_X + N,
    der Y-Wert von Sprite N liegt bei SPRITE_POS_Y + N.
    Im VIC sind die X- und Y-Werte aber leider abwechselnd angeordnet, d.h.
    der X-Wert von Sprite N liegt bei $d000 + 2 * N,
    der Y-Wert von Sprite N liegt bei $d001 + 2 * N.


    Sollten diese Formeln nicht klar sein, rechne es mit N=7 durch.

    Du meinst doch zwei mal inkrementieren, oder? Das ist ja gar nicht das selbe wie Verdoppeln!

    Wenn man von einem Koordinatenregister im VIC zu dem des nächsten Sprites gelangen möchte, kann man auch zweimal inkrementieren, richtig. In einer einfachen Schleife über alle Sprites wäre das auch sinnvoll. Die Routine im Programm ist aber so geschrieben, dass man sie für ein beliebiges Sprite aufrufen kann, dessen Nummer man im X-Register übergibt. Wenn nun die Koordinatenregister im VIC benutzt werden, muss der Adressoffset (nicht die Spritenummer!) verdoppelt werden. Damit man sich nicht die Spritenummer in X kaputtmacht, wird das Ergebnis (2 * Spritenummer) ins Y-Register geschrieben. Somit kann man die "normalen", kleinen, 8-Byte-Tabellen mit X indizieren (0, 1, 2, 3, 4, 5, 6, 7), während man die "interleaved" Koordinatenregister im VIC mit Y indiziert (0, 2, 4, 6, 8, 10, 12, 14).
    Rechne es nach, das X-Koordinatenregister für z.B. Sprite 3 befindet sich bei $d000 + 2*3,
    das Y-Koordinatenregister für z.B. Sprite 5 befindet sich bei $d001 + 2*5.

  • Keine Ahnung, ob das hier im Thread schon irgendwo erwähnt wurde:


    Jemand (smithrobs) hat sich die Mühe gemacht und ProjectJ auf GitHub abgelegt und jeden Step als eigenen Commit abgelegt:
    https://github.com/smithrobs/Endurion-ProjectJ


    Irgendwo meine ich, auch einen sauberen PDF Ausdruck aller Schritte gefunden zu haben, aber ich finde ihn gerade nicht.
    Die englischsprachige Version dieses Tutorials findet man hier: http://www.retroremakes.com/re…-game-in-several-steps/p1

  • Hoppla, hier geht's ja rund. MacBacon hat es glaube ich schon recht ausführlich erklärt:


    Die Routine ist für verschiedene Objekte ausgelegt, nicht nur für Objekte in Slot X=0. Es wird aus dem eigentlichen Objekt-Index in X (Werte von 0 bis 7) durch Verdoppeln der zugehörige Koordinaten-Offset für den VIC errechnet (aus 0,1,2,3,4,5,6,7 wird 0,2,4,6,8,10,12).


    Das sieht, wenn man nur Slot 0 betrachtet, natürlich sinnlos aus, 0 bleibt ja 0.


    Ich plane schon die ganze Zeit, das Tutorial bei C64Studio mitzuliefern. Markie hat in mühevoller Kleinarbeit alle Schritte in ein großes Dokument zusammengesetzt (danke dafür!), das ist deutlich übersichtlicher als alle Steps einzeln.

  • Wenn man von einem Koordinatenregister im VIC zu dem des nächsten Sprites gelangen möchte, kann man auch zweimal inkrementieren, richtig. In einer einfachen Schleife über alle Sprites wäre das auch sinnvoll. Die Routine im Programm ist aber so geschrieben, dass man sie für ein beliebiges Sprite aufrufen kann, dessen Nummer man im X-Register übergibt. Wenn nun die Koordinatenregister im VIC benutzt werden, muss der Adressoffset (nicht die Spritenummer!) verdoppelt werden.

    Richtig! Äh falsch. Bzw richtig erkannt: Genau damit hatte ich den Knopf:
    Den direkten Sprung in den richtigen Adressoffset erreicht man dadurch,
    dass man den Offsett = 2 * Spritenummer setzt! :)
    Also dass man die Spritenummer verdoppelt, wie ich das bemerkte
    und mir darüber eben fast mein kleines Hirnchen zerbrach... :schande:
    Ich dachte: WIESO die Spritenummer verdoppeln???
    Wieso ist jetzt zum Beispiel Sprite Nr. 8 plötzlich doppelt so sexy wie
    Sprite Nr. 4? Und warum hat Endurion jetzt plötzlich nur noch dafür
    Augen!!?? Wir waren doch schon mit Sprite Nr. 4 liasioniert! :cursing:;)


    Damit man sich nicht die Spritenummer in X kaputtmacht, wird das Ergebnis (2 * Spritenummer) ins Y-Register geschrieben. Somit kann man die "normalen", kleinen, 8-Byte-Tabellen mit X indizieren (0, 1, 2, 3, 4, 5, 6, 7), während man die "interleaved" Koordinatenregister im VIC mit Y indiziert (0, 2, 4, 6, 8, 10, 12, 14).Rechne es nach, das X-Koordinatenregister für z.B. Sprite 3 befindet sich bei $d000 + 2*3,
    das Y-Koordinatenregister für z.B. Sprite 5 befindet sich bei $d001 + 2*5.


    Fantastisch! Vielen herzlichen Dank!
    Jetzt hat es KLICK gemacht!
    :thumbsup:


    Hoppla, hier geht's ja rund. MacBacon hat es glaube ich schon recht ausführlich erklärt:


    Die Routine ist für verschiedene Objekte ausgelegt, nicht nur für Objekte in Slot X=0. Es wird aus dem eigentlichen Objekt-Index in X (Werte von 0 bis 7) durch Verdoppeln der zugehörige Koordinaten-Offset für den VIC errechnet (aus 0,1,2,3,4,5,6,7 wird 0,2,4,6,8,10,12).


    Das sieht, wenn man nur Slot 0 betrachtet, natürlich sinnlos aus, 0 bleibt ja 0.


    Ja, das ist kurz und bündig.
    Mein Problem war ja nicht nur dass es nur für ein Sprite 0 sinnlos aussieht / ist,
    sondern auch, dass ich nicht wusste und nicht verstand, dass die Routine
    für beliebige Sprite-Nummern angelegt ist (logisch hinterher) und dass
    jedes Sprite, bzw. die Koordinaten zwar um +2 weiter hinten ist, dass
    man aber eben mit der Verdoppelung der Spritenummer den OFFSET
    ab der Startadresse bekommt. Ich dachte immer, da wird bloss die
    Spritenummer verdoppelt, warum interessiert uns plötzlich ein doppelt
    weiter gezähltes Sprite so viel mehr, als das dessen Koordinaten wir
    eigentlich hätten ändern möchten?
    - Naja - bin da einfach hängengeblieben... X/
    Jedenfalls jetzt hat's geklappt. Vielen herzlichen Dank Euch beiden! :)
    Jetzt hab ich's begriffen! :-)


    Was lange währt... äh, findet manchmal auch ein Korn...
    - Oder so.


    Danke Euch beiden für die Erklärungen. Die kommen jetzt fast 1:1 in meinen
    ausführlich kommentierten Code von Step 4! :)



    LG,
    Markie