Timing und Timer. "Immer schön gleichmäßig".


Ja, ja die Zeit vergeht, dummerweise manchmal sehr schnell und manchmal sehr langsam. Dieses Phänomen beobachtet man nicht nur im realen Leben sondern auch beim Programmieren. Es tritt am häufigsten bei der Spiele-Programmierung auf. Nämlich dann, wenn man sein Spiel gerade fertig hat, es zu seinem besten Kumpel mitbringt und dort vorführen will. Dummerweise hat der Kumpel aber nicht soviel Interesse an Computern und daher ein etwas älteres und damit auch langsameres Modell "seiner Art" stehen. Das Ergebnis: Es "schleift" - und mit dem Beeindrucken ist es erst einmal vorbei. Dabei hat man sich doch solche Mühe gegeben sämtliche Pausenschleifen optimal auszutarieren.

Man sollte sich also schon vor Beginn Gedanken darüber machen, wie man auf (fast) allen Computern gleich lange Pausen erzeugt. Es gibt neben dem Standard-Timer von QuickBASIC noch andere "Zeit-Quellen" in Computern, die immer konstant sind. Wie man diese nutzen kann, zeigen diese Timing-Beispiele:

Beispiel: Timer für eine 70tel Sekunde

Beispiel: Timer für eine 19tel Sekunde

Konstantes Timing auf allen Computern

Ich möchte an dieser Stelle erklären wie man eine Pausenschleife "zusammenbaut" die auf allen Computern fast gleich lang ist. Das hier angegebene Beispiel wurde von mir und DarkBug Productions entwickelt. Es mag vielleicht nicht die beste Lösung für dieses Problem darstellen, aber es bildet einen Ansatz und funktioniert (zumindest bei mir) sehr zuverlässig.

Als erstes überlegen wir uns die Form der Pausenschleife selbst. Meistens nimmt man dafür eine FOR-NEXT Schleife. Von diesem Gedanken sollte man sich allerdings gleich wieder verabschieden. FOR-NEXT Schleifen laufen auf unterschiedlichen Rechnern für sich schon unterschiedlich schnell ab. Die bessere Lösung bieten hier Zählschleifen, also WHILE-WEND Schleifen. Eine solche Schleife hat z.B. folgenden Syntax:

Pause& = 0: WHILE Pause& < Z&: Pause& = Pause& + 1: WEND

Hierbei wird die Variable Pause& so lange um 1 erhöht bis sie den Wert der Variablen Z& erreicht. Der Trick ist nun einen Wert für Z& zu ermitteln, der von der Geschwindigkeit des Rechners abhängig ist. Wir brauchen also ein Programm welches für einen konstanten Zeitraum, sagen wir eine Sekunde, eine Variable ebenfalls um 1 erhöht. Ein solches Programm sieht z.B. folgendermaßen aus:

Start:
   ON TIMER(1) GOSUB Test
   TIMER ON
   WHILE T% = 0: Z& = Z& + 1: WEND
   TIMER OFF
   GOTO Weiter
Test:
   T% = 1
RETURN
Weiter:
...

Damit wir konstant eine Sekunde lang messen bzw. zählen, benutzen wir die ON TIMER(1)-Anweisung. D.h. jede Sekunde wird einmal ein Unterprogramm aufgerufen. In unserem Fall das Unterprogramm Test. Dies geschieht während der Ausführung unserer eigentlichen Messroutine. Diese Messroutine ist die Zeile mit der WHILE-WEND-Schleife. Diese erhöht die Variable Z&. Kurz bevor die Abarbeitung dieser Schleife beginnt, starten wir den Timer. Nun wird im Unterprogramm Test die Variable T% auf 1 gesetzt. Da T% ja nun ungleich 0 ist, hört unsere Zählschleife auf und wir stoppen den Timer und damit den Unterprogrammaufruf. Nun haben wir Z&. Dieser Wert repräsentiert für eine WHILE-WEND-Schleife, wie wir sie verwenden wollen, so ziemlich genau eine Sekunde, es gibt eine gewisse Ungenauigkeit von etwa 0.05 Sekunden. Aber auch mit dieser Ungenauigkeit ist es ein ausreichend  präziser, aber vor allem konstanter Wert. Wollen wir den Bruchteil oder ein Vielfaches einer Sekunde warten, brauchen wir diesen Wert nur noch zu berechnen. Die Ursache der Ungenauigkeit ist übrigens die Zeit, die der Computer benötigt, um die Bedingung der WHILE-WEND-Schleife abzufragen. Da die WHILE-WEND-Bedingung aber auch in unserer Warteschleife abgefragt werden muß, können wir sie vernachlässigen.

Jetzt mußt Du diesen Timer nur noch am Anfang Deines Programmes platzieren, um einmal den Wert zu messen, und kannst dann im Programm mit dem Pausenwert arbeiten. Aber Achtung, einen kleinen Haken hat diese Routine. Betätigt man irgend eine Taste dauernd während der Messung (also schläft z.B. auf der Leertaste ein bis es wie wild piepst), dann kommt man zu keinem korrekten Ergebnis. Man kann allerdings auch dieses Problem durch initialisieren eines neuen Tastaturhandlers umgehen.