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:

  1. Starten Sie QB mit /Ah neben /l. Dann können dynamische Felder größer als ein Segment (also größer als 64KB sein). Dynamische Felder sind die, die hinter 'REM $DYNAMIC' definiert wurden.
  2. Statt jedesmal 'PRINT' zu schreiben können Sie einfach ? tippen. Die IDE wandelt das Fragezeichen automatisch in ein 'PRINT' um.
  3. QB kennt den Befehl SWAP. Ein Dreieckstausch, wie ihn manche verwenden, ist unnötig.

vorheriges
Index
nächstes