Seite 1 von 2

Timer

Verfasst: 09.04.2005 17:47
von zigapeda
Hallo

Ich würde einen Timer normal mit Delay programmieren aber ich habe gehört das es das ganze programm anhält. Wenn ich also einen Timer für ein Spiel Programmiere der 2 Minuten lang zählen soll und dann die Runde beendet kann ich kein Delay nehmen weil das dann das ganze Programm anhält.

Gibt es irgent eine Möglichkeit das anhalten zu umgehen oder einen anderen befehl?

Verfasst: 09.04.2005 17:53
von Franky
Eine Möglichkeit wäre, am anfang der runde einmal EllapsedMilliseconds() auf zu rufen und dann immer am Ende der Repeatschleife den dort erhaltenen wert mit EllapsedMilliseconds zu vergleichen. Ist er 120000 oder mehr größer dem am anfang erhaltenen Wert, sind die 2 Minuten um

Verfasst: 09.04.2005 17:59
von zigapeda
wie würde das dann als code aussehen?

Verfasst: 09.04.2005 18:10
von ts-soft
Wenn du ein Fenster verwendest, kannste es z.B. so machen:

Code: Alles auswählen

Procedure MyTimer()
 ; Deine Timer Procedure
EndProcedure

SetTimer_(0, 0, 100, @MyTimer())

KillTimer_(0, 0)
Weitere Information: http://msdn.microsoft.com/library/defau ... ttimer.asp

Einfacher gehts mit PureTools von Danilo, findest Du im PureArea.net

Verfasst: 09.04.2005 22:16
von zigapeda
Jetzt hab ich noch eine andere Idee:
Ich speicher am anfang die stunde (hour(date())) minute (minute(date())) und sekunde (second(date())). dann überprüfe ich bei jedem durchlauf der repeatschleife ob schon zwei minuten zuende sind. Jetzt meine frage wie kann ich das überprüfen wenn z.B. gerade 14:59? Zwei minuten später wäre dann 15:01 wenn ich aber bei den minuten 2 dazu zähle wäre das 14:61? Was kann ich da tun? Wird das automatisch geändert oder muss ich erst mit einer Ifschleife überprüfen ob es > 14:58 ist?

Verfasst: 09.04.2005 23:10
von Kaeru Gaman
die ElapsedMilliseconds()-Lösung halte ich für am einfachsten.

Initialisierung:

Code: Alles auswählen

EndTime = ElapsedMilliseconds() + 120000
Abfage:

Code: Alles auswählen

If ElapsedMilliseconds() > EndTime
    ; die Zeit ist abgelaufen
EndIf
...oder halt als Endbedingung für ne Schleife...

Code: Alles auswählen

Until ElapsedMilliseconds() > EndTime
Achtung:
Das funktioniert nur zuverlässig, wenn der Computer nicht 14 Tage ohne Reboot läuft,
denn dann 'kippt' der Millisekunden-Zähler ins tiefste minus (weil die Long-Var voll ist)
( Long-Bereich: -2147483648 bis +2147483647)

um das zu umgehen:
Initialisierung:

Code: Alles auswählen

GoTime = ElapsedMilliseconds()
If GoTime < 2147363647
    EndTime = GoTime + 120000
Else
    EndTime = GoTime - 2147483647 + 120000 - 2147483648
EndIf
funktioniert immer, egal wie lang der Rechner an ist.
..das gesplittete minus ist nötig, um niemals die grenzen von Long zu überschreiten.

------------------------

wenn du über Hour/Minute/Second arbeiten willst, musst du 2x Überschreitungen prüfen:
jede volle Stunde und Mitternacht.

es geht nicht automatisch.

mit Milliseconds isses einfacher..

Verfasst: 09.04.2005 23:40
von THEEX
Ich speicher am anfang die stunde (hour(date())) minute (minute(date())) und sekunde (second(date())). dann überprüfe ich bei jedem durchlauf der repeatschleife ob schon zwei minuten zuende sind. Jetzt meine frage wie kann ich das überprüfen wenn z.B. gerade 14:59? Zwei minuten später wäre dann 15:01 wenn ich aber bei den minuten 2 dazu zähle wäre das 14:61? Was kann ich da tun? Wird das automatisch geändert oder muss ich erst mit einer Ifschleife überprüfen ob es > 14:58 ist?
Von Deinem Problem mit 61 Minuten mal abgesehn, ist die Lösung eh nicht wirklich gut, da die Methode recht langsam ist. Hier wurden mal einige Dinge zu Timern usw geposte, hab folgendes davon mal abgeleitet:

Code: Alles auswählen

Procedure InitElapsedMilliseconds() 
  Shared _GT_DevCaps.TIMECAPS
  SetPriorityClass_(GetCurrentProcess_(), #HIGH_PRIORITY_CLASS)
  timeGetDevCaps_(_GT_DevCaps, SizeOf(TIMECAPS)) 
  timeBeginPeriod_(_GT_DevCaps\wPeriodMin)
EndProcedure

Procedure EndElapsedMilliseconds() 
  Shared _GT_DevCaps.TIMECAPS 
  timeEndPeriod_(_GT_DevCaps\wPeriodMin) 
EndProcedure

Procedure Timer(ms)
  Static Start
  If Start = 0
    Start = timeGetTime_()
  Else
    Time = timeGetTime_() - Start
    ;Debug Time
    If  Time >= ms
      Start = 0
      ProcedureReturn #True
    EndIf  
  EndIf  
EndProcedure  



InitElapsedMilliseconds()
MessageRequester("Info", "Zeit wird gestartet")

Repeat
  If Timer(2000)
    MessageRequester("Info", "Zeit ist abgelaufen")
    EndElapsedMilliseconds()
    End
  EndIf
ForEver

Verfasst: 09.04.2005 23:43
von Kaeru Gaman
@CSprengel

ich glaube nicht, daß Danilos Hi-Res-Timer für den Minutenbereich nötig ist,
da tut es auch das standardmäßige ElapsedMilliseconds().

...ausserdem finde ich es nicht gut, einem Anfänger ohne Kommentar eine
Änderung der Prozess-Priorität unterzujubeln...

Code: Alles auswählen

  SetPriorityClass_(GetCurrentProcess_(), #HIGH_PRIORITY_CLASS) 

Verfasst: 09.04.2005 23:53
von THEEX
@Kaeru Gaman
Da wir nicht wissen, was zigapeda genau machen will, kann wohl auch kaum einer sagen, welche Genauigkeit benötigt wird.
Für Spiele würde ich selbst die Priorität unbedacht höher als auf normal setzen, wobei es natürlich wieder auf die Situtation an kommt.

Verfasst: 09.04.2005 23:57
von MVXA
Natürlich wissen wir das ;). Er braucht ein Timer für ein Spiel um herauszufinden wann eine Runde vorbei ist.