workshop16

Top  Zurück  Weiter

Workshop 16: Bugs und wie man sie los wird

Ok, nun wissen Sie also wie man Code schreibt. Sie haben gelernt mit Variablen, Funktionen, Bitmaps, Panels, Fenstern, Strings, Texten, Fonts, Entities, Aktionen, Pointers.... umzugehen. Das ist wirklich großartig, aber was passiert, wenn's schlecht aussieht und Sie niemanden fragen können, was mit Ihrem Code nicht stimmt? Warum fängt Ihr Computer , kaum dass Sie Ihr Spiel gestartet haben, plötzlich an, Popcorn aus dem Floppy-Disk-Laufwerk zu spucken? Kann mir jemand helfen? Halloooo? Ist da jemand?

Falls Ihnen der der obige Abschnitt wie das Drehbuch zu einem Horrorfilm vorkommt, gibt es etwas Beruhigendes: die Programmierer hinter der Acknex-Engine haben dafür gesorgt, dass Ihnen passendes Werkzeug zum Aufspüren und Vernichten aller Fehler im Code zur Verfügung steht. Ich möchte Sie ermuntern, die Debug-Werkzeuge so oft wie möglich einzusetzen. Oftmals gelingt es einfach nicht, die Fehler in Ihrem Code zu finden indem Sie, wie ausdauernd auch immer, auf den Inhalt Ihrer Datei starren.

Genug geredet - machen wir uns an die Arbeit! Öffnen wir die "script16"-Datei:

///////////////////////////////   
var energy = 100;

////////////////////////////////////////////////////////////////////
function decrease_energy()
{
	energy -= 40;
	if (energy < 70) 
	  vec_set(screen_color,vector(255,0,0)); // blue
	if (energy < 30)
   vec_set(screen_color,vector(0,0,255)); // red
if (energy == 0) sys_exit(NULL); } function main() { vec_set(screen_color,vector(0,255,0)); // green
on_d = decrease_energy; }

Ich sehe eine var mit dem Namen energy und dazu noch einige seltsame Dinge innerhalb der Main-Funktion... was hat es mit all diesen screen_color-Variablen auf sich?

· Vielleicht erinnern Sie sich aus unserem zweiten Workshop an screen_color. Das ist der Vektor, welcher die Hintergrundfarbe bestimmt. Ein Vektor ist eine spezielle Form einer Variablen, die nicht nur einen, sondern mehrere - meist drei - Werte beinhaltet. Diese Werte können entweder die x, y, z-Position eines Objekts in unserem Level sein, oder die Blau-, Grün-, und Rotkomponenten einer Farbe. Sie können sämtliche Kombinationen dieser 3 Farben verwenden: "blue" = 0, "green" = 0 und "red" = 0, was einen schwarze Bildschirmfarbe ergibt, bis hin zu "blue" = 255, "green" = 255, "red" = 255, wodurch ein weißer Bildschirm erzeugt wird.

Ok, wir haben in "main" also einen grüne Bildschirmfarbe gesetzt, denn screen_color.green wurde auf den Maximalwert von 255 gesetzt. Wenn ich die [D]-Taste drücke, startet die Funktion decrease_energy. Betrachten wir uns diese doch mal im Detail:

function decrease_energy()
{
  energy -= 40;
 
if (energy < 70)
    vec_set(screen_color,vector(255,0,0));
  if (energy < 30)
    vec_set(screen_color,vector(0,0,255));
  if (energy == 0)
    sys_exit(NULL);
}

Sobald wir auf die [D]-Taste drücken, wird energy kleiner, denn wir ziehen ja 40 davon ab. Wenn energy unter 70 ist, wird der Bildschirm seine Farbe in blau ändern da unsere vec_set-Funktion die erste Komponente von screen_color (blue) auf 255 und seine green- und red-Komponenten auf Null setzt. Beachten Sie, daß ein Farbvektor immer mit seiner blue-Komponente beginnt! Drücken wir nochmal auf [D], wird energy noch kleiner, unter 30, also ändert der Bildschirm seine Farbe in Rot. Wenn energy schließlich Null ist, fährt die Engine herunter. Mal sehen, ob diese Funktion das macht, was wir von ihr erwarten. Starten Sie die Skript-Datei:

w16_02

Es funktioniert! Lassen Sie mich jetzt gleich auf die Taste [D] drücken!

w16_03

Cool! Der Screen hat seine Farbe erwartungsgemäß von grün nach blau gewechselt. Ich muss nochmal auf [D] drücken!

w16_04

Das ist einfach Prima! Beenden wir die farbenfrohe Show mit einem letzten Tastendruck auf [D]!

w16_04

Hmm... Es kommt mir so vor, als hätte ich diese Farbe schon mal gesehen! Ich weiß, vielleicht ist ja die Tastatur kaputt! Ich drück' nochmal fester auf [D]!

Nein, das hat nicht funktioniert... Die Engine weigert sich herunterzufahren, wenn energy Null ist.

Ein Programm, das nicht so funktioniert wie man es erwartet, hat einen Fehler, einen Bug. Versuchen wir doch gleich jetzt, diesen Bug zu eliminieren. Schließen Sie die Engine per [Esc] (oder klicken Sie auf den [x]-Knopf). Gehen Sie zurück zu Lite-C und klicken Sie am unteren Bildschirmrand auf Watch:

w16_05

Hier haben Sie die Möglichkeit, Ihre Variablen und Objekte im Auge zu behalten. Sie können in Echtzeit beobachten, wie sich die Werte der Variablen verändern und, sogar während das Spiel läuft, lassen sich neue Werte auf die unter Beobachtung stehenden Variablen setzen! Starten wir nochmal script16 aber dieses mal unter Verwendung von Lite-C's DebugRun -Knopf anstelle von TestRun w02_08 (wenn Sie denn die Wahl haben. Einige ältere Lite-C - oder SED-Versionen haben für beides nur einen einzigen -Knopf). Beobachten wir nun gleichzeitig das Engine-Fenster und den Skript-Editoren:

w16_08

Sie sollten das Engine-Fenster (ebenso wie das Fenster von Lite-C) solange bewegen, bis Sie Lite-C's Watch-Bereich sehen können. Wenn Sie einen guten Monitor Ihr Eigen nennen, haben Sie genug Desktopplatz dafür. Jetzt fügen wir ein Watch hinzu! Klicken Sie mit der rechten Maustaste in den leeren Watch-Bereich und suchen Sie sich aus dem Pop-Up-Menü Add Watch heraus. Es erscheint ein neues Fenster, welches so aussieht:

w16_11

Geben Sie hier den Namen einer Variablen ein. In script16 haben wir nur eine Variable, also geben Sie "energy" (ohne Anführungszeichen natürlich) ein klicken Sie dann OK. Der Variablen-Name erscheint mitsamt seinem derzeitigen Wert im Watch-Bereich. Wir haben soeben einen"Watch" erstellt, einen 'Spion', der uns den Wert der Variablen namens energy verrät.

w16_13

Wie Sie sehen, ist "energy" nun 100. Je nachdem, ob Sie in Lite-C oder C-Script debuggen, könnten Sie auch drei (x, y, z) Werte anstelle von nur einem sehen. Das kommt daher, daß C-Script Variablen genauso wie Vektoren behandelt und diese können aus drei verschiedenen Komponenten mit individuellen Werten bestehen. Beobachten Sie per "watch" eine normale Variable, wie unsere energy, ist der Wert der Variablen in ihrer ersten Komponente gespeichert. Hätten Sie stattdessen var energy[3] definiert, hätten Sie energy.x = 100 für Gesundheit, energy.x = 100 für Munition und vielleicht energy.z = 20 für Geschwindigkeit nehmen können. Alles klar?

Das Programm scheint ordentlich zu laufen. Achten Sie darauf, daß das Engine-Fenster ausgewählt ist und drücken Sie einmal auf [D]:

w16_14

"Energy" wurde auf 60 gesetzt was korrekt ist, denn die erste Code-Zeile in der Funktion decrease_energy zieht von energy 40 ab. Drücken wir also nochmal auf [D]:

w16_15

Wie erwartet wurde "energy" wiederum um 40 verringert. Wenn wir jetzt noch einmal die [D]-Taste drücken, müsste die Engine herunterfahren, stimmt's?

w16_16

Na klar! Die Engine weigert sich herunterzufahren, denn energy wurde auf -20 gesetzt. Auf diese Weise wird der "if"-Zweig niemals laufen:

if (energy == 0)
  
sys_exit(NULL);

Wir müssen den Code dahingehend ändern:

if (energy < 0)
  
sys_exit(NULL);

Die Änderungen überlasse ich Ihnen. Womöglich funktioniert meine Reparatur nicht und da will ich besser nicht in der Nähe sein, wenn Sie die neue Variante des Programms testen...

Weiter: Debugging für Fortgeschrittene