Tipps 2/10
Information
Nützliche Tipps für QB
Dieses Kapitel ist im Grunde eine Sammlung vieler kleiner Kapitel, bei denen es sich nicht lohnte ein echtes Kapitel draus zu machen.
Kleine Optimierungen
Wenn Sie Zahlen quadrieren wollen, verwenden Sie 'x * x' statt 'x ^ 2'. Das geht etwa 20 mal schneller. Ebenfalls sollte 'x + x' statt '2 * x' verwendet werden. Falls Sie es vergessen haben sollten: In QB existiert der Operator '\', der eine Intgerdivision durchführt. Also statt 'INT(x/y)' schreibt man einfach 'x \ y', was kürzer und vor allem wesentlich schneller ist.
Wenn Sie sicher sind, dass es sich um positive Zahlen handelt verwenden sie immer 'INT' statt 'FIX', da 'INT' wesentlich schneller ausgeführt wird.
Zeit
Häufig muss ein Programm abgebremst werden, z.B. damit man eine Animation überhaupt sieht und nicht nur ein seltsames geflimmer. Anfänger verwenden hierfür oft 'FOR'-Schleifen, die einfach sinnlos ein wenig hochzählen. Allerdings berechnet jeder Computer sie unterschiedlich schnell. Deswegen verwenden Fortgeschrittene den Timer von QB, der unter eben diesem Namen angesprochen werden kann. Allerings ist er recht langsam. Deshalb sollten Sie lieber den Timer, der sich bei 0040:006Ch befindet verwenden:
DEFINT A-Z SUB WaitClockTicks (ticks&) DEF SEG = &H40 FOR i& = 1 TO ticks& status = PEEK(&H6C) DO LOOP WHILE satatus = PEEK(&H6C) NEXT DEF SEG END SUB
Dieser Timer wird, wie der QB-Timer, alle 18,5 Sekunden aktualisiert, ist aber schneller auslesbar.
Ein Problem, das auch mit Timing zu tun hat, ist das Bildflimmern, das entsteht, wenn Sie ihr Bild schneller aufbauen, als die Bildwiederholrate ihres Monitors. Um das zu vermeiden können Sie auf die nächste vertikale Synchronisation warten:
WAIT &H3DA, 8 WAIT &H3DA, 8, 8
Sprites
In Spielen, aber auch in vielen anderen Situationen slen sich Grafiken über einen Hintergrund bewegen. Dabei entstehen zwei Probleme: Erstens muss der Hintergrund wiederhergestellt werden, nachdem sich die Grafik eiterbewegt hat. Das zweite ist, dass Teile des Bildes durchsichtig sein sollen. Solche kleinen Grafiken, die sich durchs Bild bewegen, nennt man übrigens Sprite.
Folgender Trick zeigt, wie Sie ein Sprite malen können, ohne den Hintergrund zu löschen. Dazu benötigen Sie drei Felder:
einen Puffer, der den vorherigen Bildschirminhalt speichert, eine Maske, in der alle sichtbaren Teile 0 sein müssen und alle unsichtbaren Bereiche die höchste verfügbare Farbe haben (255 in SCREEN 13, 15 in SCREEN 12, etc.). Ich sage absichtlich nicht weiß, wie es in einigen Texten zu finden ist, da Weiß lediglich eine Definition der Palette ist, und es bei diesem Verfahern aber um den konkreten Index dreht. Das schließlich letzte Feld ist das eigentliche Sprite, wobei die durchsichtigen Teile 0 sein müssen.
Das ganze wird wie folgt verwendet:
PUT (oldx, oldy), puffer, PSET ' ersetze die alte Position GET (x1, y1)-(x2, y2), puffer ' lade den neuen Bereich PUT (x, y), maske, AND ' verknüpfe die Maske AND mit dem Hintergrund PUT (x, y), sprite, XOR ' Verknüpfe das Bild mit XOR ' oder bei invertierter Maske PUT (x, y), maske, OR ' verknüpfe die Maske OR mit dem Hintergrund PUT (x, y), sprite, AND ' Verknüpfe das Bild mit AND
Paletten
Um die Palette zu verändern dient der Befehl 'PALETTE'. Allerdings ist er extrem langam. Wesentlich schneller geht es mit folgendem Code:
DEFINT A-Z SUB SetPal (col AS INTEGER, r AS INTEGER, g AS INTEGER, b AS INTEGER) OUT &H3C8, col OUT &H3C9, r OUT &H3C9, g OUT &H3C9, b END SUB DEFINT A-Z SUB GetPal (col AS INTEGER, r AS INTEGER, g AS INTEGER, b AS INTEGER) OUT &H3C7, col r = INP(&H3C9) g = INP(&H3C9) b = INP(&H3C9) END SUB
'ALIAS' missbrauchen
Sie können 'ALIAS' missbrauchen. Es ist bekanntlich dafür gedacht einen Namen für eine Funktion durch einen anderen zu ersetzen, weil der Originalname in QB unzulässig ist. Da leigt dann daran, dass die Funktion in einer anderen Sprache geschreiben wurde, in der es sich um einen legalen Namen handelt.
Sie können aber jeder Funktion aus einer Bibliothek einen anderen Namen geben. Hat eine Funktion einen komplizierten Namen, können Sie 'ALIAS' missbrauchen, um ihr einen einfacheren Namen zu geben.
DECLARE SUB Einfach ALIAS "SehrKomplizierterNameDerZuLangIst"
Die Aktuelle Auflösung
Wenn Sie die Aktuelle Auflösung herusfinden wollen, können Sie folgenden Code verwenden:
SUB Resolution (X AS INTEGER, Y AS INTEGER) DEF SEG = 0 ' Ließ die Zeichenbreite im aktuellen Viedeomodus DIM ScreenWidth AS INTEGER ScreeenWidth = PEEK(&H44A) ' Multipliziere die Zeichenbreite mit 8 um die Breite des Bildschirms zu berechnen ScreenWidth = ScreenWidth * 8 ' Ließ Zeichenhöhe und Anzahl der Zeichen DIM ScreenHeight AS INTEGER, CharHeight AS INTEGER ScreenHeight = PEEK(&H484) + 1 CharHeight = PEEK(&H485) ' Das Produkt der letzten beiden Werte ergibt die Bildschirmhöhe ScreenHeight = ScreenHeight * CahrHeight x = ScreenWidth y = ScreenHeight END SUB
Kleinigkeiten:
Wenn man längere Zeit eine Taste hält fängt der Computer plötzlich an zu piepen. Das liegt daran, dass der Tastaturpuffer voll läuft. Folgender Code behebt dieses Problem, indem er den Tastaturpuffer leert:
DEF SEG = 0 POKE &H41A, PEEK(&H41C)
Statt mit 'INKEY$' die Taste einzulesen können Sie 'INP(&H60)' verwenden. Allerdigs erhalten Sie dann nicht den ASCII-Code, sondern den Scancode. Dafür geht es wesentlich schneller, als mit 'INKEY$'.
Beenden mit Fehlerwert
Programme können Fehlercodes ans Betriebssystem zurückgeben. Diese können unter DOS mit ERRORLEVEL abgefragt werden. Um QB mit Fehlercode zu verlassen verwenden Sie folgendes:
DECLARE SUB ExitWithErrorLevel ALIAS "_exit" (BYVAL errorlevel AS INTEGER)
Entfernungen
In vielen Spielen müssen immerwieder Entfernungen verglichen Werden. Dazu verwenden alle den Satz des Pytagoras. Entfernungen sind immer positiv und für zwei positive Zahlen gillt, wenn A größer B ist, dann ist auch A2 größer B2. Und das Quadrat der Wurzel einer positiven Zahl ist die Zahl selbst. Also kann man statt:
IF SQR(x1 * x1 + y1 * y1) > SQR(x2 * x2 + y2 * y2) THEN ...
können Sie auch folgendes verwenden:
IF x1 * x1 + y1 * y1 > x2 * x2 + y2 * y2 THEN ...
Errinerungen
Dieser Abschnitt errintert nochmal kurz an ein paar Tatsachen: