Minigame programmieren


  • fenris64
  • 4895 Aufrufe 73 Antworten

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Minigame programmieren

    Hallo,
    habe mich nun weiter in asm reingefuchst, hatte schon lange eine Spielidee im Kopf, die ich gerne verwirklichen würde, aber man muss sich ja erstmal realistische Ziele setzten...
    Aus diesem Grunde habe ich mich entschieden erstmal ein kleines Minigame zu machen, welches ich glaube ich schon hinkriegen könnte:
    Und zwar soll es ein kleiner Shooter werden, nicht falsch verstehen, wirklich nichts dolles, ich dachte an ein Raumschiff (1x Multicolorsprite plus 1x Normalsprite für den Schuss), ein leicht veränderter Char-Satz, wo ich ein paar Zeichen zu "Gesteinsbrocken" umpixel. Diese Gesteinsbrocken könnte ich mit mit einer Softscrollroutine (in der Art vom hier vorgestellten Tutorial von biguser) von links nach rechts bewegen, diesen müsste man ausweichen, zugleich entstünde ein "Scrolleffekt", damit man auch wirklich denkt, dass man von links nach rechts fliegt. Nun hätte man ja noch einige Sprites für Gegner über (auch Multicolor, sieht glaub ich ganz gut aus), eventuell noch ein Extra wie Bombe zum einsammeln und Space oder doppelter Joystickfiredruck zum auslösen.
    Noch ein Multicolorbild als Startscreen, eine einfache Musicabspielroutine und fertig wäre mein erstes Minispiel!

    Ok, ich denke die Asmprofis hätten das in ner Viertelsunde fertig, aber ich werde schon ein paar Wochen brauchen :rotwerd:
    Ich habe gerade dieses Programmierziel gewählt, weil ich ähnliches schon in Basic realisieren konnte, das Spiel aber natürlich viiieeel zu langsam war, als dass man brauchbar spielen konnte!

    Bin gerade dabei die ersten Sprites zu zeichnen und werde dann versuchen die Yoystickroutine zu basteln, werde dann wohl die nächsten Wochen immer mal etwas mit Fragen nerven :winke:

    Jetzt hätte ich schon mal diese Fragen
    1. Bei Kollisionen von Sprites habe ich schon irgendwo gelesen, dass es ein Register gibt, in denen Kollisionen registriert werden und man je nach reingeschriebener Zahl weiß, welche Spritenummern zusammengestoßen sind, dass krieg ich also schon irgendwie hin. Aber wie mache ich es am besten bei Zusammenstößen zwischen Char- Zeichen und Sprite (hier:z.B. Zusammenstoß von Raumschiff und Gesteinbrocken)? In Basic habe ich es mehr oder minder so gemacht, dass ich geguckt habe, wo das Charzeichen war (meinetwegen in 1500 o.ä.), diese Position dann umgerechnet habe in eine Spriteposition (also 1- 255 x und 1-255 y), und dann die Kollisionsabfrage gemacht habe. Geht das irgendwie einfacher in asm?
    2. Kennt ihr ein gutes Tutorial für die Bearbeitung und Implementierung eines neues Char- Satzes?

    Danke im Voraus,
    Fenris64
  • Ganz einfach, der VIC bietet nämlich 2 Register für Sprite Kollisionsabfragen.
    Einmal das Register 53278 ($D01E) für Sprite-Sprite-Kollision und 53279 ($D01F) für Sprite-Hintergrund-Kollision (in deinem Fall das Charset)

    Wenn du vorhast den Zeichensatz zwecks Spielegrafik zu verändern wäre vielleicht Char Pad was für dich -> noname.c64.org/csdb/release/?id=26959


    Gruß
    "Sometimes I pretend to be normal, but it gets boring. So I go back to being me."
  • Cool, es gibt auch ein Register für Char- Zusammenstöße mit Sprites, das hilft sehr!
    Habe noch mal bei C64 Wiki nachgeschlagen, wie es sich mit den Auslesewerten bei Sprite- Sprite zusammenstößen und bei Sprite- Char zusammnestößen verhält.
    Dort steht:
    • 53278 Kollision zwischen Sprites; Auslesewerte X=0 (keine Kollison) bis 255 (1, 2, 4, 8, 16, 32, 64, 128 für Sprite 0 bis 7; Kombinationen mit Addition der Werte für mehrere Sprites z.B. 3 für Sprite 0 und 1)
    • 53279 Kollision zwischen Sprites und Hintergrund (Zeichen); Auslesewerte X=0 (keine Kollision) bis 255 (1, 2, 4, 8, 16, 32, 64, 128 für Sprite 0 bis 7; Kombinationen mit Addition der Werte für mehrere Sprites z.B. 3 für Sprite 0 und 1)
    Bei Sprite- Sprite- Zusammenstößen habe ichs kapiert: Stoßen meinetwegen Sprite 0 und Sprite 2 zusammen, steht im Register 53278 der Wert 5 (1 plus 4)
    Bei einem Sprite- Char- Zusammenstoß werde ich aus der Erklärung überhaupt nicht schlau, ist das bei Wiki ein Fehler? Warum steht dort auch was von einer Kombination von Werten der Sprites, es gibt dort doch nur ein Sprite, welches mit einem Char zusammenstößt.. :roll:
    Weiß einer, wie sich der Wert im Register 53279 errechnet? Logisch wäre doch irgendeine Art Verknüpfung von Spritewert mit Charwert (also bei A=1)???

    Was das Programm angeht sieht es natürlich richtig gut aus, aber ich glaube es ist etwas zu mächtig für mich am Anfang, bräuchte vielleicht erstmal eine Erklärung, ab wo die Wete für die Chars stehen (speziell: wo stehen Bitwerte von Char "A", wo die Werte von "B" etc. und wie tausche ich die gegen eigene aus, außerdem wie sind die Chars aufgebaut bzw. wie erstelle ich eigene, ich denke ja mal ähnlich wie Sprites???)

    Aber so weit erstmal danke für die Hilfe!
  • Die Kollisionsregister haben für jede Kollision ein Bit gesetzt. D.h. in der 53279 können natürlich auch mehrere Bits gesetzt sein, was mehreren Sprites entspricht. Dementsprechend ist die Kombination gemeint.

    Noch ein Haken beim Sprite/Sprite-Kollisionsregister: Wenn zwei Sprite-Pärchen kollidieren, kannst du nicht wirklich erkennen, welches Sprite mit welchem kollidiert ist.

    Beispiel: Sprite 1 und 2 kollidieren und Sprite 3 und 4 kollidieren. Dann sind alle 4 Bits der Sprites gesetzt. Du kannst jetzt daran nicht sagen, ob Sprite 1 mit 2, oder mit 3 oder mit 4 kollidiert ist.
  • OK, dass habe ich dann auch verstanden, nur noch nicht so ganz mit der Sprite- Char- Kollision: Ist es denn so, dass man in dem Register somit nur auslesen kann, DASS ein Sprite mit einem Char- Zeichen kollidiert ist, aber nicht mit welchem?

    Beispiel Sprite 0 stößt mit Char- Zeichen "A" zusammen:
    In 53279 steht dann eine "1", heiß Sprite 0 ist mit irgendeinem Char zusammengestoßen...

    Habe ich das richtig verstanden?
  • fenris64 schrieb:

    Und zwar soll es ein kleiner Shooter werden, nicht falsch verstehen, wirklich nichts dolles
    Spielspaß hängt weniger von der ausgefeilten Programmierung ab als von der Originalität des Programmierers! Mach was schönes, unterleg das ganze mit krachiger Mucke, knall einen Startscreen davor und am besten das ganze gleich für zwei Spieler simultan! Und dann bitte auf der DT veröffentlichen! :freude

    Etwas Inspiration!
    Was bedeutet dieses dämliche Modewort "retro" eigentlich wirklich?
    Wer mir dummdreiste Unterstellungen macht, kriegt Ärger mit meinem Freund Supererdbeere!
  • @green: Ja gerne, ich bin glaub ich mit pixeln nicht so begabt, hätte wahrscheinlich nur irgendein Bild von einem Raumschiff konvertiert und den Namen vom Spiel drübergepixelt :thumbsup: Wäre cool, wenn du da was machen würdest, zum einen kriegt du bestimmt was besseres hin als ich, zum anderen ist eine kleine Zusammenarbeit auch was cooles :hammer: Würde aber noch warten, bis zumindest eine funktionierende Grundengine steht, bin wie gesagt blutiger Anfänger und ich muss das überhaupt erstmal alles hinbekommen (aber ich werde so lange kämpfen, bis ein kleines Game fertig ist), auch damit du weißt, wie du überhaupt ein Titelbild gestalten könntest... (z.B. muss man sich ja noch Namen überlegen usw.) Format ist übrigens egal, hauptsache Multicolor, Speicherbereiche des Bildes kann man ja problemlos ändern...

    ok, habe wieder ein kleines Problem mit dem Programm (soll einfach Bild schwarz machen und Multicolorsprite anzeigen), stürzt im Turboassembler sofort ab mit blauen Bildschirm:
    *=C000
    jsr $e544 ; Bildschirm löschen
    lda #$00 ; Bildschirm in schwarz
    sta $d020
    sta $d021
    lda #01
    sta $d01c ; Multicolor Spr1
    ldx #$40 ; Man möchte 64 Spritedaten einlesen, daher X=63 ($3f), hier $40, weil am
    ; Ende noch einmal y um 1 erhöht wird, nachdem 63 Werte gelesen
    ;wurden
    ldy #$00
    sprin lda sprdat,y ; lese aus Tabelle Spritedaten, immer plus y, damit immer neue Werte
    ; geladen werden…
    sta $3000,y ; Spritedaten ab §3000 abspeichern
    dex ; x um 1 verringern, wenn x 0 ist, sind alle Daten gelesen
    iny ; y um 1 erhöhen, um nächsten Wert aus Tabelle zu holen
    beq sprin ; solange x nicht 0 ist wieder zu sprin springen!
    lda sprdat+63 ; Spritefarbe holen ; letzte Zahl in Tabelle ist Farbe!!!
    sta $d027 ; und Farbe setzen ($do27= 53281)
    lda #$80 ; X-Position #128 (Sprite 1)
    sta $d000
    lda #$80 ; Y- Position #128 (Sprite 1)
    sta $d001
    lda #$c0 ; Spritepointer Sprite 1 setzen
    sta $07f8 ; $3000 = $c0*$40 $07f8= 2040
    ;Die Zeigerwerte für die Spritedaten 0 bis 7 stehen in den Adressen 2040 bis 2047 (0x07f8 bis 0x07ff). Der Zeigerwert
    errechnet sich aus der Anfangsadresse der Spritedaten geteilt durch 64. Empfohlen werden kann der Kassettenpuffer
    (Speicheradresse 832 bis 1022 für Spriteblock 13,14,15) und der obere Speicherplatz (z.B. von 12288 bis 12798 mit den
    Spriteblöcken 192 bis 199). Weil Spritedaten hier ab §3000 (geteilt durch 64= 192= §c0)
    lda #$00 ; bei 1 Spritezoom, aber ausgeschaltet
    sta $d017 ; X-Zoom
    sta $d01d ; Y-Zoom
    lda #§01 : 1 wenn nur Sprite1, 3 wenn Sprite 1 und 2 …
    sta $d015 ; =#53269 ; Sprite 1 an
    rts
    sprdat .byte $ff, $ff, $ff, $ff, $ff, $ff
    .byte $ff, $ff, $ff, $ff, $ff, $ff
    .byte $ff, $ff, $ff, $ff, $ff, $ff
    .byte $ff, $ff, $ff, $ff, $ff, $ff
    .byte $ff, $ff, $ff, $ff, $ff, $ff
    .byte $ff, $ff, $ff, $ff, $ff, $ff
    .byte $ff, $ff, $ff, $ff, $ff, $ff
    .byte $ff, $ff, $ff, $ff, $ff, $ff
    .byte $ff, $ff, $ff, $ff, $ff, $ff
    .byte $ff, $ff, $ff, $ff, $ff, $ff
    [font='&quot'] .byte $ff, $ff, $ff, $0e [/font]
    Ach ja, Spritedaten habe ich natürlich andere (Für Multicolorsprite, 64 Werte plus einen für die Farbe)

    @Tele: Mal schauen, wie es am Ende wird, ich gebe mir größte Mühe, aber ich muss eben erst Erfahrung sammeln...
  • Das größte Problem dürfte die Kopierschleife sein, tausche mal dex und iny, sonst stimmt die Abbruchbedingung nicht.
    Setz dann noch mal die Farben anders, damit man das Sprite besser sehen kann.

    Sonst ist da nur noch der Tipper:

    lda #§01 : 1 wenn nur Sprite1, 3 wenn Sprite 1 und 2 …

    Soll vermutlich

    lda #$01 : 1 wenn nur Sprite1, 3 wenn Sprite 1 und 2 …

    sein
  • habe dex und iny vertauscht, jetzt will turboass vorm assemblieren prüfen, aber das bild wird grau und dann hängt das Programm, habe aber jetzt rausgefunden, dass man im Vice ja auch den Quellcode kopieren kann, muss dann nicht mehr abschreiben: also hier nochmal der Code, wie ich ihn ganz genau in Turboass drin habe:

    SQL-Abfrage

    1. *= $c000
    2. jsr $e544;screen leer
    3. lda #$00
    4. sta $d020
    5. sta $d021
    6. lda #1
    7. sta $d01c;multicolor
    8. ldx #$40;64 Spritedaten
    9. ldy #$00
    10. sprlesen lda sprdat,y
    11. sta $3000,y;sprdaten ab$3000
    12. iny
    13. dex
    14. beq sprlesen
    15. lda sprdat+63;Farbe holen!
    16. sta $d027;Farbe setzen
    17. lda #$80
    18. sta $d000; x pos sp1
    19. lda #$80
    20. sta $d001; y pos sp1
    21. lda #$c0; sprpointer
    22. sta $07f8;=2040
    23. lda #$01
    24. sta $d015;spr 1 an
    25. rts
    26. sprdat .byte $00,$00,$00,$00,$00
    27. .byte $00,$00,$00,$00,$00
    28. .byte $00,$00,$00,$00,$00
    29. .byte $00,$00,$00,$00,$00
    30. .byte $00,$00,$00,$00,$00
    31. .byte $00,$00,$00,$00,$00
    32. .byte $40,$05,$a0,$50,$15
    33. .byte $a8,$35,$55,$55,$35
    34. .byte $55,$40,$51,$51,$50
    35. .byte $00,$04,$04,$00,$15
    36. .byte $55,$50,$00,$00,$00
    37. .byte $00,$00,$00,$00,$00
    38. .byte $00,$00,$00,$00,$07
    39. x:9 line:40 bot:8e83 insert: line
    40. turbo-ass v5.1 - special flt version -90
    41. x:0 line:1bot:8e83 insert: line
    Alles anzeigen


    Wenn ich mit Pfeil links und "3" assemblieren möchte, erscheint nur
    turbo ass .by wolfram roemhild

    copyright 85 by omikron germany

    improved by bacchus




    ***** end of pass 1
    first adress : c000
    last adress : c079

    und Hintergrund wird gräulich und Programm hängt, kann mit Control aber wieder in den Assembler...
  • Stimmt, habe ihn neu gestartet und C000 in 1000 geändert, hängt sich nicht mehr auf :roll:
    Worin liegt das denn, der Tasm liegt doch bei $9000 oder nicht? Na ja, stürzt auf jeden Fall nicht ab, nur ist jetzt irgendwie der Sprite totaler Müll, muss mal forschen warum das jetzt so ist...

    Auf jeden Fall vielen Dank für den Tip, auf sowas soll man erstmal kommen...
  • Ok, wieder einen Fehler gefunden: Das Programm, welches ich zum Zeichnen der Sprites verwendet habe (Spritepad), gibt, obwohl man im Multicolor- Modus zeichnet, die Spritewerte wenn man sie als Textfile haben möchte, nur als Nicht- Colormodus- Werte aus, kein Wunder also, dass mein Sprite wie Müll aussah, aber immerhin ist der Code also richtig :)

    Hat jemand zufällig ein Spritetool für den PC, wo man Multicolor- Sprites zeichnen kann und die Werte irgendwie als Textfile oder so ausgeben kann?
  • @fenris64: $c000 geht (so) nicht, weil der TASS natürlich nicht nur das eine Byte an Adresse $9000 belegt, sondern alle von $9000 bis $cf00. Und auch den Speicher darüber kann man nicht gefahrlos benutzen, weil dort Daten über die Labels beim Übersetzen abgelegt werden.

    Wenn man Routinen in diese Speicherbereiche legen möchte, dann muss man die nicht in den Speicher, sondern direkt in eine Datei übersetzen lassen. Was natürlich bedeutet, dass man die vor dem Ausprobieren erst wieder laden muss. Und da sie bei $9000 bis $cf00 Teile des TASS überschreiben, muss man den neu laden, wenn man wieder am Quelltext arbeiten möchte.
    “I am Dyslexic of Borg, Your Ass will be Laminated”
  • Außerdem muss man drauf achten, dass der Sourcecode ja auch noch im Speicher liegt. Bei großen Projekten, die viel Speicher brauchen kommt man deshalb nicht umhin immer öfter die "Assemble to Disk" Funktion zu nutzen. Wenn man ein RR oder MMCR, dann kann alternativ schonmal den TASS vom Turbo Action Rom nutzen. Der packt schonmal den Sourcecode ins RR-Ram und man hat etwas mehr Platz.
    turbo.style64.org/info.php?cid=Turbo_Action_ROM_v1
  • Klar, habe mal wieder beq und bne verwechselt :rotwerd:
    Hier soll ja gerade NICHT verzweigt werden, wenn x =0 ist ! :aerger:

    Die Multifarben hatte ich noch hinzugefügt, nur vergessen das noch zu posten... Erstmal vielen Dank für die Tips, Programm läuft jetzt und Sprite wird genau wie geplant ordnungsgemäß angezeigt! Dann werde ich mich jetzt an die Implementierung der Joysticksteuerung machen!