Erstellt: 6. Oktober 2013 (zuletzt geändert: 1. November 2021)

Landung 006

Ganz schön anziehend

C64 Studio

Da es langweilig und unnütz ist, das Landungsschiff einfach so über den Bildschirm zu bewegen, fügen wir jetzt etwas Physik (ich schäme mich das gleich kommende so zu bezeichnen) hinzu. Basis ist natürlich das Programm aus dem vorherigen Beitrag.

Gravitation

Wie die Erde, besitzt auch PB5-78841 eine Anziehungskraft. Sorgen wir also dafür, dass diese auf unser Schiff einwirkt. Jetzt könnten wir dem Planeten eine Anziehungskraft zuweisen, dem Schiff eine Masse, Reibung, Gegenschub usw. festlegen und ein komplexes Rechenmodell entwickeln, das all dies verarbeitet. Viel Spaß dabei… 😉

Wir halten es da dann doch etwas einfacher. Wird nichts unternommen, dann sinkt das Schiff mit zunehmender Zeit immer schneller. Sobald man den Feuerknopf drückt, wird die untere Schubdüse aktiviert. Um so länger der Knopf gedrückt wird, desto größer wird der Schub und sobald die abwärts Bewegung gestoppt ist, steigt das Schiff.

Wie setzen wir dass nun um?

Um auch sanfte Bewegungen zu erreichen, wäre es schön, wenn wir Sprites auch um 0,2 oder 0,6 Pixel bewegen könnten. Dass geht natürlich nicht, aber wir könnten die Sprite-Position und Geschwindigkeit mit Nachkommazahlen verwalten. Da richtige Fließkommazahlen für unser Vorhaben zu aufwendig sind, bauen wir uns unsere eigenen Kommazahlen. Laßt uns einfach zwei Bytes verwenden, das LSB stellt den Nach- und das MSB den Vorkommateil dar. Dass unsere Zahlen in kein normales Zahlensystem passen, soll uns (im Gegensatz zu den nun mit den Augen rollenden Mathematikern) nicht weiter stören. Es geht schließlich nur darum, die gewünschte Bewegung zu erreichen.

2 * 3 macht 4
Widdewiddewitt und Drei macht Neune
Ich mach mir die Welt
Widdewidde wie sie mir gefällt…

Beginnen wir mit dem Hinzufügen von neuen Konstanten und Variablen. Um die Gravitation, X- und Y-Beschleunigung festzulegen. Richten wir erstmal drei neue Konstanten ein:

GRAVITY             = $08           ;Anziehungskraft
THRUST_X            = $04           ;Schubkraft seitwärts
THRUST_Y            = $06           ;Schubkraft aufwärts

Ersetzt jetzt noch die bisherige Variable SpaceshipPos durch folgenden Block:

Spaceship_PosX
 !byte $00
 !byte SPACESHIP_STARTX              ;X- und  
Spaceship_PosY
 !byte $00
 !byte SPACESHIP_STARTY              ;Y-Position des Landungsschiffs

Spaceship_SpeedX
 !word $00
Spaceship_SpeedY
 !word $00

Hier haben wir jetzt also unsere „Kommazahlen“. Die Berechnung von Spaceship_Pos erfolgt nun mit Vor- und Nachkommaanteil. Neu hinzugekommen ist noch Spaceship_Speed, damit sorgen wir für die Beschleunigung in die verschiedenen Richtungen. Die Geschwindigkeit initialisieren wir mit 0, die Position wird wie bisher initialisiert, nur dass wir diesmal darauf achten, nur den Vorkommateil zu füllen und den Nachkommateil auf 0 zu setzen.

In der Funktion updateSprites setzen wir jetzt die Position der Sprites nicht mehr einfach, sondern wir berechnen Sie über die aktuellen Geschwindigkeiten aus Spaceship_Speed. Passt dazu die Funktion an die neuen Gegebenheiten an.

!zone updateSprites
;*******************************************************************************
;*** Sprites positionieren
;*******************************************************************************
;*** Übergabe: -
;*******************************************************************************
;*** Sprites positionieren
;*******************************************************************************
;*** Übergabe: -
;*******************************************************************************
;*** Rückgabe: -
;*******************************************************************************
;*** ändert  : A, X, SR
;*******************************************************************************
updateSprites
 lda Spaceship_SpeedX               ;LSB der X-Geschwindigkeit in den Akku
 clc                                ;C-Flag für Addition löschen
 adc Spaceship_PosX                 ;zum LSB der X-Pos. addieren
 sta Spaceship_PosX                 ;und speichern
 lda Spaceship_SpeedX+1             ;jetzt das MSB der X-Speed in den Akku
 adc Spaceship_PosX+1               ;zum MSB der X-Pos. addieren (C wird beachtet)
 sta Spaceship_PosX+1               ;und speichern
 tax                                ;X-Position (nur Vorkommateil) 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                   ;und positionieren

 tax                                ;nochmal die X-Position holen
 dex                                ;und linkes 'Feuer'
 dex                                ;um drei Pixel nach links
 dex                                ;verschieben
 stx VIC_SPRITE2X

 lda Spaceship_SpeedY               ;LSB der Y-Geschwindigkeit in den Akku
 clc                                ;Carry löschen
 adc Spaceship_PosY                 ;LSB der Y-Pos. addieren
 sta Spaceship_PosY                 ;und speichern
 lda Spaceship_SpeedY+1             ;MSB der Y-Geschwindigkeit in den Akku
 adc Spaceship_PosY+1               ;MSB der Y-Pos. addieren
 sta Spaceship_PosY+1               ;speichern und 
 sta VIC_SPRITE0Y                   ;für alle fünf Sprites übernehmen
 sta VIC_SPRITE1Y                
 sta VIC_SPRITE2Y                
 sta VIC_SPRITE3Y                
 sta VIC_SPRITE4Y         
 rts                                ;zurück

Wie ihr seht, addieren wir zu Beginn die X-Geschwindigkeit auf die X-Position, speichern die neue Position und setzen die Sprites auf den „Vorkommateil“. Am Ende machen wir das Gleiche mit der Y-Position und -Geschwindigkeit.

Auch die Eingabe-Routine muss natürlich an die neue Logik angepasst werden.

!zone checkInput
;*******************************************************************************
;*** Joystickeingabe prüfen
;*******************************************************************************
;*** Übergabe: -
;*******************************************************************************
;*** Rückgabe: Letzte Eingabe in InputState
;*******************************************************************************
;*** ändert  : A, X, Y, SR, InputState
;*******************************************************************************
checkInput
 lda VIC_SPRITEACTIVE               ;alle Flammen für die Düsen
 and #%11110001                     ;ausblenden und
 tax                                ;im X-Register merken

 jsr joystickInput                  ;Aktuellen Joystick-Status holen
 and #%00011111                     ;Nur die unteren 5-BIT sind von Interesse
 eor #%00011111                     ;Da Low-Aktiv, umkehren
 beq .noFire                        ;keine Eingabe, dann ENDE

 lsr                                ;rauf und
 lsr                                ;runter benötigen wir nicht
 lsr                                ;links?
 bcc .right                         ;falls nicht rechts prüfen
 tay                                ;Akku im Y-Reg. retten
 txa                                ;sichtbare Sprites (X-Reg.) in den Akku
 ora #%00001000                     ;Feuerschub rechts sichtbar
 tax                                ;wieder im X-Reg. merken
 sec                                ;C-Flag für Subtraktion setzen
 lda Spaceship_SpeedX               ;LSB der X-Geschwindigkeit in den Akku
 sbc #THRUST_X                      ;X-Beschleunigung abziehen
 sta Spaceship_SpeedX               ;speichern
 lda Spaceship_SpeedX+1             ;MSB der X-Geschwindigkeit holen
 sbc #$00                           ;ggf. C-Flag addieren
 sta Spaceship_SpeedX+1             ;und ebenfalls speichern
 tya                                ;Akku zurücksetzen
.right
 lsr                                ;rechts?
 bcc .fire                          ;falls nicht, Feuernknopf prüfen
 tay                                ;wieder Akku im Y-Reg. retten
 txa                                ;sichtbare Sprites holen
 ora #%00000100                     ;diesmal Feuerschub links aktivieren
 tax                                ;wieder im X-Reg. merken
 clc                            
 lda Spaceship_SpeedX               ;wie eben, nur dass jetzt
 adc #THRUST_X                      ;addiert wird
 sta Spaceship_SpeedX
 lda Spaceship_SpeedX+1
 adc #$00
 sta Spaceship_SpeedX+1
 tya                                ;Akku zurückholen
.fire
 lsr                                ;Feuerknopf gedrückt?
 bcc .noFire                        ;falls nicht Anziehungskraft addieren -> noFire:
 txa                                ;diesmal direkt X in den Akku holen
 ora #%00000010                     ;Feuerschub unten aktivieren
 tax                                ;wieder im X-Register merken
 sec                            
 lda Spaceship_SpeedY               ;kein nennenswerter Unterschied zur
 sbc #THRUST_Y                      ;links/rechts Beschleunigung
 sta Spaceship_SpeedY
 lda Spaceship_SpeedY+1
 sbc #$00
 sta Spaceship_SpeedY+1
.exit
                                    ;im X-Register stehen die sichtbaren 
 stx VIC_SPRITEACTIVE               ;Sprites, die wir jetzt wieder setzen
 rts                                ;zurück

.noFire                             ;Falls der Feuerknopf nicht gedrückt ist
 clc                                ;addieren wir die Gravitation
 lda Spaceship_SpeedY               ;dass funktioniert wie weiter oben
 adc #GRAVITY
 sta Spaceship_SpeedY
 lda Spaceship_SpeedY+1
 adc #$00
 sta Spaceship_SpeedY+1
 jmp .exit                          ;zum Ende springen

Statt wie bisher, direkt die X- / Y-Position zu verändern, bestimmen wir jetzt mit der Joystick-Eingabe die Geschwindigkeit in die jeweilige Richtung. Dazu addieren bzw. subtrahieren wir (fast identisch zur Position im vorangegangenen Block) unsere Konstanten für die X- / Y-Beschleunigung bzw. Gravitation zum „Nachkommateil“ und beachten dann noch das C-Flag, um auch den „Vorkommateil“ bei einem Übertrag zu verändern.

Durch die neue Speicherung der Position und der Geschwindigkeit, müssen wir auch initLander anpassen.

!zone initLander
;*******************************************************************************
;*** Leveldaten zurücksetzen
;*******************************************************************************
;*** Übergabe: -
;*******************************************************************************
;*** Rückgabe: -
;*******************************************************************************
;*** ändert  : A, X, Y, SR
;*******************************************************************************
initLander
 lda #$00                           ;'Nachkommastellen' löschen
 sta Spaceship_PosX            
 sta Spaceship_PosY
 sta Spaceship_SpeedX               ;Geschwindigkeit löschen   
 sta Spaceship_SpeedX+1
 sta Spaceship_SpeedY
 sta Spaceship_SpeedY+1
 lda #SPACESHIP_STARTX              ;Startposition setzen
 sta Spaceship_PosX+1               ;X
 lda #SPACESHIP_STARTY              ;und
 sta Spaceship_PosY+1               ;Y
 jsr initSprites                    ;Sprites initialisieren
 jsr drawCanyon                     ;den Canyon zeichnen
 rts                                ;zurück

Hier jetzt auch die Vor- und Nachkommastellen für die Position und Geschwindigkeit korrekt initialisieren.

Bevor das Programm gestartet werden kann, bedarf es noch einer letzten kleinen Änderung. Sucht das Label .laser beim Raster-IRQ. Kurz dahinter findet ihr die Stelle lda SpaceShipPos+1, diese muss in lda Spaceship_PosY+1 ;MSB der Y-Pos. des Raumschiffs in den Akku geändert werden.

Jetzt sollte sich das Programm starten lassen und ihr könnt das Landungsschiff mit dezenten Schüben kontrollieren.

Auf einen Screenshot verzichte ich, den Unterschied zum letzten Beitrag erkennt man nur, wenn man das Programm selbst ausführt.


Im kommenden Teil sollten wir uns mal um die Kollisionserkennung kümmern, damit es endlich eine Herausforderung für den Spieler gibt. Bis dahin spielt mit den Werten etwas herum und schaut wie sich das Programm verhält.


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

Loading...


ZurückWeiter

Schreibe einen Kommentar

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

Protected by WP Anti Spam