Autor | Thema: Zeiverzoegerung im Programm | | Datum:09.07.02 23:04 
(twanzke@aol.com) | |
Hi,
ich habe einen Bildschirmschoner programmiert. Damit er mit unterschiedlichen Prozessoren nicht unterschiedlich schnell abläuft, lasse ich die Zeit mit &GetTickCount zweimal ermitteln und benutze die Differenz beider Werte um die Ausführung zu beeinflussen (wie Ihr mir das hier im Forum erklärt habt).
Ohne diese Zeitermittlung läuft der Bildschirmschoner problemlos. Mit der Zeitermittlung im Programm kommt es vor, daß das Programm nicht mehr korrekt funktioniert. Der Bildschirmschoner läßt sich zwar durch eine Mausbewegung oder einen Tastendruck beenden, aber die Ausgabe des Bildes wird nicht mehr ausgeführt.
Ich kann leider nicht herausfinden, woran das liegt. Habt Ihr eine Erklärung?
Hier der Code des Programms:
Declare A%,B%,E%,F%,X%,Y%,Test%,Wert&,Wert1&,Wert2&,Zufall%,Zaehler%
Declare Ini$,P$,Pfad$,Wert$,Wert1$
Dim% 36
PROC Zeichnung
If @EQU(Zufall%,0)
Let A%=0
Let B%=0
ElseIf @EQU(Zufall%,1)
Let A%=61
Let B%=0
ElseIf @EQU(Zufall%,2)
Let A%=122
Let B%=0
***
ElseIf @EQU(Zufall%,35)
Let A%=305
Let B%=315
EndIf
Let E%=X%+A%
Let F%=Y%+B%
MCopyBmp A%,B%-61,63 > E%,F%;0
ENDPROC
PROC Initialisierung
Let Zaehler%=0
While @LT(Zaehler%,36)
List% Zaehler% = 0
Inc Zaehler%
Wend
Let Zaehler%=0
ENDPROC
PROC Zeitmessung
Let Wert&=&GetTickCount
ENDPROC
If %ParCount
Let P$=@Upper$(@Par$(1))
EndIf
If @EQU$(P$,"/A")
@MessageBox("(C) 2002","Info",64)
ElseIf @NEQ$(P$,"/P")
Let Ini$=@ReadIni$("SYSTEM.INI","BOOT","SCRNSAVE.EXE")
WriteIni "SYSTEM.INI","BOOT","SCRNSAVE.EXE"="(Kein)"
RANDOMIZE
WindowStyle $F0
Window 0,0-%MaxX,%MaxY
Cls @RGB(31,31,31)
ShowCursor 0
Let Test%=3
Let Zaehler%=0
Let X%=@Div&(%MaxX,2)
Let Y%=@Div&(%MaxY,2)
Let X%=@Sub(X%,183)
Let Y%=@Sub(Y%,189)
Let Pfad$=@Add$($WinPath,"/BILD.BMP")
MLoadBmp Pfad$
Initialisierung
Zeitmessung
While @Gt(Test%,0)
Case %GetInputState:Dec Test%
If @EQU(Wert2&,1000)
If @LT(Zaehler%,36)
Let Zufall%=@Rnd(36)
IF @EQU(@List%(Zufall%),1)
Let Zufall%=@Rnd(36)
Else
List% Zufall% = 1
Inc Zaehler%
EndIf
Zeichnung
ElseIf @EQU(Zaehler%,36)
Cls @RGB(31,31,31)
Let Zaehler%=0
Initialisierung
EndIf
Zeitmessung
EndIf
Let Wert1&=&GetTickCount
Let Wert2&=@Sub(Wert1&,Wert&)
Wend
WriteIni "SYSTEM.INI","BOOT","SCRNSAVE.EXE"=Ini$
ShowCursor 1
EndIf
End
Für Eure Hilfe bedanke ich mich im voraus.
Thomas Wanzke
|
| | Datum:10.07.02 08:36 
(schmidts@flat2serv.de) | |
Hi,
ich habe mir Deinen Quelltext zwar nicht so genau angeschaut, aber Du solltest niemalds eine Endlos-Schleife basteln, das geht selten gut. Nutze besser Sleep oder einen Timer, um der Anwendung ein wenig Zeit zum reagieren zu geben.
Mfg.
Sven Schmidts
|
| | Datum:10.07.02 12:36 
(joerse@gmx.de) | |
Hallo Thomas,
So wie ich Dein Programm verstehe bringst Du in regelmäßigen Abständen
Teile eines Bildes auf den Schirm.
Dafür ist es eigentlich nicht wichtig, die Prozessorleistung zu berücksichtigen.
Das wäre nötig bei Animationen, damit die nicht rast oder ruckelt.
Du kannst also Deine Zeitmessung weglassen. Sie macht eigentlich sowieso
nichts anderes als ein Sleep 1000.
Der unregelmäßige Ablauf und wohl auch das nicht angezeigte Bild, sind eher
auf Deinen Zufallsgenerator zurückzuführen.
Wenn nur noch wenige Stellen "frei" sind braucht es eben seine Zeit, um die
richtige Zahl zu Treffen. Und mit einer Sekunde Wartezeit kann das schon mal
dauern.
Wenn Du das mit einbaust:
Case %GetInputState:Dec Test%
Locate 1,1
print Zufall%,&gettickcount
siehst Du, daß Deine Bedingung für den Zufallsgenerator irgendwo hakt.
Einen zuverlässigen Zufallsgenerator kannst Du mit einer Listbox erzeugen:
Window 10,10 - 400,600
Decimals 0
Declare Listbox&,Zähler%,Zahl%
Let Listbox& = CreateListBox(%hwnd,"",100,10,200,400)
Proc ListeFüllen
Let Zähler%=0
Randomize
WhileNot Equ(zähler%,36)
AddString(Listbox&,Str$(Zähler%))
Inc Zähler%
Wend
EndProc
Proc Zufallszahlen
WhileNot Equ(zähler%,-1)
Zahl%=Rnd(Getcount(Listbox&))
print GetString$(Listbox&,Zahl%)
DeleteString(Listbox&,Zahl%)
Dec Zähler%
Wend
EndProc
Proc EineZufallszahl
Zahl%=Rnd(Getcount(Listbox&))
print GetString$(Listbox&,Zahl%)
DeleteString(Listbox&,Zahl%)
EndProc
ListeFüllen
Zufallszahlen
While 1
WaitInput
If Equ(Getcount(Listbox&),0)
ListeFüllen
Cls
EndIf
EineZufallszahl
wend
Übrigens werden bei mir nur 3 Puzzleteile angezeigt. Ist das so richtig ?
Ich hoffe ich konnte Dir helfen.
Gruß
Jörg
|
| | Datum:10.07.02 15:43 
| |
Hallo Thomas,
meines Erachtens ist die Zeile...
If @EQU(Wert2&,1000)
...schuld.
So wie ich's verstanden hab' steht in Wert2& die schon vergangene Zeit in Millisekunden. Wäre allerdings reiner Zufall, wenn dieser Wert genau 1000 ist. Benutze @GT oder @LT, aber nicht @EQU. Je nach dem, wie du abfragen willst.
Deine Technik der Zeitmessung ist schon richtig, Sleep oder ein Timer nützt dir gar nichts. Nur durch die Messung der vergangenen Zeit kannst du ein Programm auf allen Computern gleich schnell ausführen lassen. Das ist schon richtig so.
Die ProSpeed.dll bietet einige Zeitmessungs-Funktionen an:
StartWatch ()
Startet eine Stoppuhr, deren Stand mit ReadWatch() gelesen werden kann.
ReadWatch ()
Ermittelt die Anzahl der Millisekunden, die seit dem letzten Aufruf von StartWatch() vergangen sind.
WaitWatch (M)
Wartet, bis mindestens M Millisekundenn seit dem letzten Aufruf von StartWatch() vergangen sind.
Gruß, Frank
|
| | Datum: 10.07.02 15:50 
| |
P.S.
Auch zu Thema Zufallsgenerierung wirst du bei der ProSpeed.dll fündig:
Random (B,L,A,M)
Schreibt eine beliebige Anzahl generierter Zufallswerte in einen Bereich.
B : Long - Bereich, der die Zufallszahlen aufnehmen soll.
L : Long - Anzahl Longs, die in den Bereich geschrieben werden sollen (1 Long = 4 Byte)
A : Long - Wert, der zu jeder Zufallszahl addiert werden soll, oder 0
M : Long - Maximumwert der zu generierenden Zufallszahlen
Ergebniss: Long - 0
Alle Zufallszahlen, die generiert werden, werden als LongInteger in den Speicher (Bereich) geschrieben. Der Bereich muß vorher natürlich
ausreichend dimensioniert werden.
Es werden Zahlen erzeugt, die zwischen 0 und M-1 liegen, anschließend wird noch A hinzu addiert (A darf auch negativ sein).
Beispiele:
'*** Erzeugt in Bereich# 100 Zufallszahlen zwischen 1000 und 1199)
Random (bereich#,100,1000,200)
'*** Erzeugt in Bereich# 4000 Zufallszahlen zwischen -1000 und 0)
Random (bereich#,4000,-1000,1000)
'*** Erzeugt in Bereich# 30 Zufallszahlen zwischen 0 und 1)
Random (bereich#,30,0,2)
|
|
|