Erstellt: 14. Juli 2013 (zuletzt geändert: 1. November 2021)

Landung 003

Das Raumschiff „zusammenbauen“

C64 Studio

Diesmal geht es darum, unser Raumschiff auf den Bildschirm zubringen. Aber leider werden wir dann gleich wieder ausgebremst! Sollten Probleme auftreten, benutzt einfach den letzten Beitrag Landung 002 als Ausgangspunkt.

Das Raumschiff anzeigen

Wie bereits bei Landung 001 erklärt, besteht das Raumschiff aus zwei übereinanderliegenden Hi-Res-Sprites und drei MultiColor-Sprites. Zur Erinnerung, im Editor sollten die Sprites ungefähr so aussehen:

Die ersten Sprites.
Die ersten Sprites.

Wer mit den Sprites noch auf Kriegsfuß steht, sollte evtl. nochmal bei Sprites (ASM) nachschlagen.

Fügt jetzt vor dem Label screenCanyon, die Sprites ein (s. gelb hervorgehobene Zeilen).

;*** Die Sprites
!align 63,0
spriteSpaceship
 !media "Ship.spriteproject",sprite,0,5


;*** Der Canyon
screenCanyon
 !media "Canyon.charscreen",charcolor

Wir richteten die Sprites natürlich wieder, an einer durch 64 teilbaren Adresse aus. Legen ein Label (hier spriteSpaceship) fest und binden die dazugehörige Datei (bei mir „Ship.spriteproject“) ein.

Dann gibt es wieder zwei Konstanten, die am Programmbeginn benötigt werden.

SPACESHIP_STARTX    = $a5           ;X-Position und
SPACESHIP_STARTY    = $32           ;Y-Position, an der das Schiff startet

In der Funktion initLander fügen wir vor das jsr drawCanyon die folgenden, gelb markierten, Zeilen ein.

initLander
 lda #SPACESHIP_STARTX              ;Startpositione setzen
 sta SpaceshipPos                   ;X
 lda #SPACESHIP_STARTY              ;und
 sta SpaceshipPos+1                 ;Y
 jsr initSprites                    ;Sprites initialisieren
 jsr drawCanyon
 rts

Hier wird einfach die X- & Y-Startposition in die Variable SpaceshipPos geschrieben, die z. B. hinter LaserFlash eingefügt werden kann.

SpaceshipPos
 !byte SPACESHIP_STARTX             ;X- und  
 !byte SPACESHIP_STARTY             ;Y-Position des Landungsschiffs

Da zur Initialisierung der Sprites, nach initSprites gesprungen wird, brauchen wir natürlich noch die entsprechende Funktion. Legt diese hinter der Routine initLander ab.

!zone initSprites
;*******************************************************************************
;*** Sprites initialisieren
;*******************************************************************************
;*** Übergabe: -
;*******************************************************************************
;*** Rückgabe: -
;*******************************************************************************
;*** ändert  : A, X, SR
;*******************************************************************************
initSprites
 ldx #spriteSpaceship/64            ;Nr. des ersten 64-Byte-Sprite-Blocks
 stx SPRITEPOINTER0+4               ;Spritedaten zuweisen
 inx
 stx SPRITEPOINTER0+0
 inx
 stx SPRITEPOINTER0+2
 inx
 stx SPRITEPOINTER0+3
 inx
 stx SPRITEPOINTER0+1

 jsr updateSprites                  ;Sprite-Positionen setzen

 lda #COLOR_BLACK                   ;Farben der Sprites setzen
 sta VIC_SPRITE0COLOR

 lda #COLOR_LIGHTGREY
 sta VIC_SPRITE4COLOR

 lda #COLOR_RED
 sta VIC_SPRITEMULTICOLOR0
 lda #COLOR_YELLOW
 sta VIC_SPRITEMULTICOLOR1

 lda #%00001110                     ;nur die "Feuer"-Sprites sind MultiColor
 sta VIC_SPRITEMULTICOLOR

 lda #%00000000
 sta VIC_SPRITEDEEP
 sta VIC_SPRITEDOUBLEWIDTH
 sta VIC_SPRITEDOUBLEHEIGHT

 lda #%00010001                     ;erstmal nur das 'Schiff' anzeigen
 sta VIC_SPRITEACTIVE

 rts                                ;zurück

Zu Beginn wird wieder die Spriteposition berechnet (zur Abwechslung mal direkt vom Assembler). Anschließend werden die Spritedaten auf die Sprite-Nr. verteilt. Hier ist es wichtig auf die korrekte Reihenfolge zu achten. Die Details (schwarzes Sprite) sollten die Nr. 0 begkommen, um alles Andere zu überdecken. Dann folgen „Feuer unten“ (Nr. 1), „Feuer links“ (Nr. 2), „Feuer rechts“ (Nr. 3) und der Schiffsrumpf (großes graue Sprite) wird (Nr. 4). Die Feuerdüsen müssen in dieser Reihenfolgen abgelegt werden, damit das Einblenden nachher korrekt klappt. Der Rest sollte kein Problem sein. Über updateSprites werden einmal die Sprite-Positionen gesetzt, dann Farben, MultiColor, Doppeltebreite usw. festgelegt und schließlich Sprite 0 und 4 sichtbar geschaltet.

Bevor wir das Programm wieder starten können, wird noch eine weitere Funktion benötigt, die ihr am besten direkt, hinter initSprites einfügt.

!zone updateSprites
;*******************************************************************************
;*** Sprites positionieren
;*******************************************************************************
;*** Übergabe: -
;*******************************************************************************
;*** Rückgabe: -
;*******************************************************************************
;*** ändert  : X, SR
;*******************************************************************************
updateSprites
 ldx SpaceshipPos                   ;X-Position holen
 stx VIC_SPRITE0X                   ;für Sprite-0
 stx VIC_SPRITE1X                   ;1 und
 stx VIC_SPRITE4X                   ;4 übernehmen
 inx                                ;rechtes 'Feuer'
 inx                                ;um drei Pixel nach rechts
 inx                                ;verschieben
 stx VIC_SPRITE3X
 ldx SpaceshipPos                   ;nochmal die X-Position holen
 dex                                ;und linkes 'Feuer'
 dex                                ;um drei Pixel nach links
 dex                                ;verschieben
 stx VIC_SPRITE2X
 ldx SpaceshipPos+1                 ;Y-Position
 stx VIC_SPRITE0Y                   ;für          
 stx VIC_SPRITE1Y                   ;alle
 stx VIC_SPRITE2Y                   ;Sprites
 stx VIC_SPRITE3Y                   ;identisch
 stx VIC_SPRITE4Y         
 rts                                ;zurück

Diese Funktion positioniert alle Sprites so, dass diese jederzeit an der richtigen Stelle stehen. Zu Beginn wird die X-Position aus SpaceshipPos geholt. Für die Details, den Rumpf und „Feuer unten“ passt dieser Wert. Die Feuerdüsen für links und rechts müssen aber etwas verschoben werden, bis sie an der richtigen Stelle erscheinen. Zum Schluß müssen noch alle Sprites auf die korrekte Y-Position gesetzt werden und schon kann die Funktion verlassen werden.

Endlich können wir uns das Ergebnis mal ansehen.

Wie man direkt sieht, haben wir ein kleines Problem. Habt ihr das Programm bis hierher unverändert übernommen und auf einem PAL-System gestartet, dann sollte euch ein Flackern des Himmels auffallen. Aktiviert ihr auch nur ein Sprite mehr ist der Himmel fast dauerhaft braun statt blau, aktiviert ihr aber nur ein einziges Sprite sieht wieder alles gut aus.

Hier seht ihr die Probleme, sobald das Sprite sichtbar ist.

Daher unterbrechen wir hier erstmal wieder, um im nächsten Beitrag zu klären, was da gerade schiefgeht.


Dies ist übrigens ein schönes Beispiel dafür, dass man sich bei der Entwicklung unter Windows nie zu sicher sein sollte. Je nach Emulator kann es z. B. sein, dass sich der Fehler nicht oder anders zeigt. Auch wenn VICE und CCS64 echt super sind, ein Programm sollte zusätzlich immer auf einem echten C64 getestet werden. Um so trickreicher eure Effekte sind, um so wichtiger wird dies natürlich. Die Grenzbereiche der Hardware sind eher ein Problem für Emulatoren, als die Hausmannskost.


Schrott!!Naja...Geht so...Ganz gut...SUPER! (3 Bewertungen | Ø 5,00 von 5 | 100,00%)

Loading...


ZurückWeiter

2 Gedanken zu „Landung 003“

  1. Hi,
    Darf man hinter einem incbin keinen ;rem machen? Habe jetzt fast eine Stunde lang nach dem Bug gesucht. Ich hatte ganz unten incbin "lander.spt",1,5,true ;rem Kommentar, dann passen die Sprites nicht mehr. Komisch.
    Schönen Urlaub noch.

    1. Hallo,
      ja du hast recht (wieder mal 😉 ).
      Ein Kommentar hinter dem TRUE führt dazu, dass dieses nicht mehr korrekt ausgewertet wird. Die Sprites werden dann nicht auf 64-BYTEs aufgefüllt!

      Da dies auch bei meiner BETA 3.1 noch der Fall ist, habe ich Arthur das Problem mitgeteilt.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Protected by WP Anti Spam