Landung 007

Für diesen Beitrag wurde das CBM prg Studio verwendet.
weitersagen ...
Tweet about this on TwitterShare on FacebookShare on Google+Share on LinkedIn

CBM prg StudioThe Eagle has landed

Nun ist es an der Zeit, dass wir auf eine Kollision reagieren und natürlich ebenfalls prüfen, ob das Landungsschiff sicher aufgesetzt hat. Basis ist (wie jedesmal) der Download aus dem letzten Beitrag ‚Landung 006‚.

 

Eine Kollision erkennen
Um festzustellen, ob es zu einer Kollision mit dem Hintergrund gekommen ist, prüfen wir einfach das VIC-II Register 31 ( $D01F / VICSPRITEBACKGROUNDCOLL). Auf einen extra Interrupt (der ja durchaus möglich ist) verzichten wir. Schreiben wir also erstmal eine kleine Routine, die das Register prüft. Fügt diese am besten direkt hinter dem jmp gameloop: ein.

Wie ihr an der Einleitung erkennen könnt, soll die Routine Kollisionen und die korrekte Landung (folgt weiter unten) erkennen. Die neue Variable Alive: wird nun verwendet, um den Status des Landungsschiffes anzuzeigen.  Alive: erhält den Wert -1 / #$FF, solange das Raumschiff unbeschädigt ist. Bei einer Kollision wechselt Alive: auf 0, um die Zerstörung anzuzeigen. Ein perfekte Landung wird mit einer 1 gekennzeichnet.
Die Funktion holt sich einfach den Inhalt des VIC-Registers 31 in den Akku. Da die Düsen nicht geprüft werden müssen, maskieren wir einfach alles aus, so dass die beiden Hauptsprites (0 & 4) des Landungsschiffes übrig bleiben. Anschließend prüfen wir, ob eine Kollision stattgefunden hat (dann ist der Akku ungleich 0). Gab es keine Kollision, wird die Routine einfach verlassen, anderenfalls erhält Alive:, wie eben erwähnt, den Wert 0, bevor die Funktion endet.

Jetzt brauchen wir natürlich noch die neue Variable. Fügt diese am besten hinter der Variablen InputState: ein.

Außerdem sollten wir nicht vergessen den Wert korrekt zu initialisieren. Sucht dazu die Routine  init_lander: und fügt direkt an den Anfang diese zwei Zeilen hinzu:

 

Wir müssen natürlich noch auf eine Kollision reagieren, dazu erweitern wir einfach unsere Hauptschleife gameloop:. Ersetzt nun die Anweisung jmp gameloop: mit diesem Block.

Hinter gameloop: springen wir zu unserer neuen Routione checkCollision: und holen danach Alive: in den Akku. Ist  Alive: negativ, dann springen wir einfach wieder zu gameloop:. Dies geschieht solange, bis sich der Wert von  Alive: ändert. Sobald dieser nicht mehr negativ ist werden erstmal die Interrupts gesperrt, anderenfalls könnte sich das Schiff noch bewegen. Es wird dann geprüft, ob der Wert 0 ist (also eine Kollision stattgefunden hat). Bei einem Zusammenstoß geht es beim gameover: weiter. Dort deaktivieren wir alle Sprites, laden den Akku mit der Farbe rot und warten darauf, dass der Feuerknopf gedrückt wird.
Bei einer Landung wird nur grün in den Akku geholt und dann zu waitForFire: gesprungen.
Bei waitForFire: setzen wir Rahmen- und Hintergrundfarbe auf den Wert aus dem Akku. Danach benutzen wir drei Prüfungen für den Feuerknopf. Die erste wartet, bis der evtl. noch gedrückte Knopf losgelassen wird. Wir könnten ja mit aktiven Schub irgendwo reingedonnert sein. Ist der Knopf nicht mehr gedrückt, dann warten wir, bis er gedrückt wird. Würden wir jetzt sofort unser Spiel neustarten käme es gleich wieder zum Unglück (probiert es ruhig mal aus), das Landungsschiff würde sofort in den Laser fliegen. Daher warten wir (bei der dritten Abfrage) mit dem Neustart, bis der Feuerknopf wieder losgelassen wird. Dann geht es weiter zu Label main:. Fügt dieses abschließend noch am Programmbeginn direkt vor jst init_lander: ein.

Startet ihr das Programm, dann wird sehr wahrscheinlich sofort eine Kollision angezeigt:

Kollision!!!
Kollision!!!

Erst nach einem Druck auf den Feuerknopf geht es wirklich los. Wir haben hier vergessen das Kollisionsregister zu löschen. Durch das Initialisieren der Sprites wurde versehentlich eine Kollision ausgelöst. Also noch mal die Funktion init_lander: aufsuchen und am Ende (vor dem rts) das Register einmal lesen, damit es gelöscht wird:

Jetzt sollte das Programm korrekt starten.

 

Vom Laser verbrutzelt
Wer direk mal ‚Vollgas‚ gibt, wird feststellen, dass der Laser uns immer noch nicht aufhält. Der Grund sollte jedem klar sein, er ist kein Teil des Hintergrundes und wird somit von unserer Prüfung bisher nicht erkannt. Lasst uns in der Routine updateSprites: prüfen, ob das Schiff den Laser berührt. Dazu begeben wir uns ans Ende und fügen vor die Zeile sta VICSPRITE0Y ;für alle fünf Sprites die kleine Prüfung ein.

Durch die vorherigen Anweisungen befindet sich im Akku die aktuelle Y-Position der Sprites. Diese vergleichen wir mit der letzen ‚Laser-Zeile‚. Findet keine Berührung statt, springt das Programm einfach zu @skip:, sonst wird Alive: wieder auf 0 gesetzt, um die Zerstörung zu kennzeichnen, bevor es bei @skip: weitergeht.

Schon werdet ihr feststellen, dass das Programm jetzt auch endet, falls ihr den Laserstrahl berührt.

 

Aufgesetzt
Ich hoffe ihr habt nicht versucht das Schiff wirklich zu landen. Denn bisher ist das unmöglich. Egal wie sanft ihr in der grünen Landezone aufsetzt, das Schiff wird zerstört. Auch hierfür fehlt natürlich noch unsere Prüfung!

Um die Landung zu erkennen müssen wir nur die neue Funktion checkCollision: noch etwas erweitern. Auch bei einer Landung lassen wir zunächst eine Kollision auftreten, allerdings prüfen wir dann über ‚absolute‚ Werte, ob der Landebereich getroffen wurde. Dazu müssen wir ermitteln welche X- & Y-Werte für den Landebereich zulässig sind. Befindet sich das Schiff innerhalb dieses ‚Fensters‚, dann ist eine perfekte Landung wahrscheinlich, sonst haben wir das Ziel verfehlt und das Landungsschiff wird wiedermal zerstört. Dieses Vorgehen ist natürlich nicht sehr flexibel, aber da wir nur einen festen Bereich haben, finde ich, dass hier durchaus OK.

Der glebe Bereich inkl. der roten Linie ist 'sicher'
Der glebe Bereich inkl. der roten Linie ist ‘sicher‚

Um dass mal zu verdeutlichen, werft einen Blick auf die obige Grafik. Dort seht ihr zur Veranschaulichung ausnahmsweise zwei Sprites. Diese zeigen die äußerst linke und rechte Landeposition an. Die weißen Punkte markieren die obere / linke Ecke des Sprites, dies ist unsere X- & Y-Position. Bilden wir nun ein Rechteck nach unten mit diesen Eckpunkten, dann erhalten wir die sichere Landezone. Außerdem bemerkt ihr bestimmt, dass das Sprite sich bereits im grünen Landebereich befindet. Wir erhalten also eine Kollision. Nur dann müssen wir prüfen, ob sich das Sprite (Y-Position) unter der roten Linie befindet. Ist dies der Fall, dann prüfen wir ob sich die X-Position innerhalb des gedachten Rechteckes befindet. Dabei muss natürlich beachtet werden, dass links an der Landezone eine weitere Kollisionsmöglichkeit besteht. Treffen alle Prüfungen zu, dann wurde die Landezone ‚getroffen‚, sonst zerschellt das Schiff.

Übernehmt die nächsten Zeilen hinter der Anweisung beq @exit: ;falls nicht, weiter -> @exit:.

Wir vergleichen hier die X- & Y-Position des Schiffes, ob diese innerhalb der Landezone liegen. Dabei beachten wir natürlich, dass die Position immer die linke obere Ecke des Sprites angibt. Die Werte wurden also entsprechend der Spritegröße angepasst. Sind wir in der Landezone, dann wird noch geschaut, ob die Sink- und links/rechts-Geschwindigkeit niedrig genug war. Wir wollen schließlich, dass das Schiff sanft gelandet wird. Um dies zu prüfen, schauen wir uns die aktuelle X- & Y-Geschwindigkeit an. Ist der ‚Vorkommateil‚ der beiden Werten 0, dann gehen wir von einer korrekten Landung aus.
Stimmen schließlich alle Vorgaben, wird eine 1 nach Alive: geschrieben, um die perfekte Landung zu kennzeichnen. Weicht auch nur ein Wert ab, wird das Schiff, wie bei jeder Kollision, zerstört.

Jetzt könnt ihr euch an einen Testlauf wagen und versuchen, dass Schiff, im Canyon, sicher ans Ziel zubringen.

Geschafft, das Schiff ist sicher gelandet.
Geschafft, das Schiff ist sicher gelandet.

 

Wir können uns noch um zwei Kleinigkeiten kümmern. Einmal ‘steht‚ das Schiff bei der Landung etwas zu niedrig (wir haben ja erst bei einer Kollision reagiert). Außerdem könnte es passieren, dass trotz Landung eine der Düsen sichtbar bleibt. Korrigieren wir also die Spriteposition und schalten zur Sicherheit die Düsen ab. Das machen wir im gameloop: direkt hinter dem Kommentar ;sonst -> gelandet mit diesen Anweisungen:

 


Langsam nähert sich der Level seinem Ende. Wir wollen aber noch dafür sorgen, dass der Spieler sich nicht unnötig lange mit der Landung aufhält und werden als nächstes noch den Spritverbrauch einbauen.

Wie gewohnt, gibt es hier wieder die Möglichkeit für den Start im Java-Emulator. Dort kommt es beim ersten Start übrigens immer noch zu einer unerwünschten Kollision, dies liegt aber an JaC64. Bei anderen Emulatoren (z. B. WinVICE, CCS64 oder Hoxs 64) und auf einem C64 funktioniert alles wie erwartet.


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

Loading...


 

<<< zurück | weiter >>>

 

weitersagen ...
Tweet about this on TwitterShare on FacebookShare on Google+Share on LinkedIn

Schreibe einen Kommentar


Beachtet bitte, dass ich eure Kommentare erst manuell freigegeben muß, bevor sie auf der Seite erscheinen! Da ich nicht pausenlos am Rechner sitze, kann es schon mal etwas dauern, bis ein Kommentar für alle sichtbar ist.

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

Protected by WP Anti Spam