Allgemeine Fragen zur PROFAN Programmierung
Views (Heute): 242857 (4293)
  Suchen
 Zurück zur Übersicht
 AutorThema: Zeiverzoegerung im Programm
Thomas Wanzke
Datum:09.07.02 23:04 Antwortenals Email verschicken (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



Sven Schmidts
Datum:10.07.02 08:36 Antwortenals Email verschicken (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


Jörg Sellmeyer
Datum:10.07.02 12:36 Antwortenals Email verschicken (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


Frank Abbing
Datum:10.07.02 15:43 Antwortenals Email verschicken  


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



Frank Abbing
Datum: 10.07.02 15:50 Antwortenals Email verschicken  


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)



 Zurück zur Übersicht