Timer

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
zigapeda
Beiträge: 1753
Registriert: 06.03.2005 17:22
Wohnort: Kaufbeuren
Kontaktdaten:

Timer

Beitrag 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?
kluger Mann + kluge Frau = Romanze | dummer Mann + dumme Frau = Schwangerschaft
kluger Mann + dumme Frau = Affäre | dummer Mann + kluge Frau = Shopping <)
Benutzeravatar
Franky
Beiträge: 1132
Registriert: 29.08.2004 16:31
Wohnort: Münsterland
Kontaktdaten:

Beitrag 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
Falsch zugeordnetes Zitat des Tages: "O'zapft is" - Edward Snowden :)
Benutzeravatar
zigapeda
Beiträge: 1753
Registriert: 06.03.2005 17:22
Wohnort: Kaufbeuren
Kontaktdaten:

Beitrag von zigapeda »

wie würde das dann als code aussehen?
kluger Mann + kluge Frau = Romanze | dummer Mann + dumme Frau = Schwangerschaft
kluger Mann + dumme Frau = Affäre | dummer Mann + kluge Frau = Shopping <)
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag 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
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
zigapeda
Beiträge: 1753
Registriert: 06.03.2005 17:22
Wohnort: Kaufbeuren
Kontaktdaten:

Beitrag 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?
kluger Mann + kluge Frau = Romanze | dummer Mann + dumme Frau = Schwangerschaft
kluger Mann + dumme Frau = Affäre | dummer Mann + kluge Frau = Shopping <)
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag 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..
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
THEEX
Beiträge: 804
Registriert: 07.09.2004 03:13

Beitrag 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
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag 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) 
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
THEEX
Beiträge: 804
Registriert: 07.09.2004 03:13

Beitrag 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.
Benutzeravatar
MVXA
Beiträge: 3823
Registriert: 11.09.2004 00:45
Wohnort: Bremen, Deutschland
Kontaktdaten:

Beitrag von MVXA »

Natürlich wissen wir das ;). Er braucht ein Timer für ein Spiel um herauszufinden wann eine Runde vorbei ist.
Bild
Antworten