Seite 1 von 2
Wie lang soll ein Delay() sein?
Verfasst: 15.09.2004 15:16
von sbehrens
Hi @all,
ich wollte mich erkunden, wie lang eigentlich ein Delay() sein sollte. Irgendwie habe ich mir mal angewöhnt, immer einen 20ms langen Delay zu benutzen (habe ich glaube ich aus einem Example), im Forum sehe ich aber immer nur Delays der Länge einer Millisekunde... Ist das nicht ein bisschen zu kurz, oder is 20ms zu lang?
thx im Vorraus,
mfG
Basti
Verfasst: 15.09.2004 16:02
von Ynnus
kommt drauf an wofür der Delay sein soll. Ich hab bisher nur immer Delays verwendet wenn ich einen langsamen Rechner simulieren wollte und die Framerate daher künstlich runtergrücken wollte.
Bei Anwendungen macht man das imo, damit eine endlosschleife nicht 100% Systemauslastung hervorruft. Da reicht aber meist 1 ms aus. Ich hab in meinen Fenster-Anwednungen überhaupt keine. Das kommt natürlich auch auf das Programm an. Ein Uhrzeiger-Programm welches jede Sekunde aktualisiert wird, muss ja kein delay(1) haben, da reicht es ja, wenn das ein 1000er ist. Und der Programmcode wird ja auch recht schnell abgearbeitet. Somit ist eine Pause von einer milisekunde schon recht lang, im Verhältnis zu keiner Pause.
Als kleines Beispiel zur Verdeutlichung der recht langen Pause bei einer ms:
Code: Alles auswählen
time = ElapsedMilliseconds()
For x = 0 To 100000000
z = z + 1
Next x
MessageRequester("","Benötigte Zeit ohne Delay: "+ Str(ElapsedMilliseconds() - time))
time = ElapsedMilliseconds()
For x = 0 To 1000
z = z + 1
Delay(1)
Next x
MessageRequester("","Benötigte Zeit mit Delay: "+ Str(ElapsedMilliseconds() - time))
Die erste Schleife ohne Delay durchläuft er 100000001 mal. Bei mir in ~ 250 ms.
Die erste Schleife mit Delay(1) durchläuft er gerade mal 1001 mal. Bei mir in ~ 2000 ms.
Man sieht da also schon einen extremen Unterschied zur Variante ohne Delay.

Verfasst: 15.09.2004 16:48
von Lars
Ein anderer guter Wert für die Mainloop mit Window Event Handling ist 10-
15. Letztendlich Geschmackssache

Verfasst: 15.09.2004 18:42
von benny
@pTI:
Für den Fall, dass Deine Hauptschleife z.B. konstant alle 30 msec abge-
arbeitet werden soll - sollte die Delay-Zeit immer so hoch sein, so viel
msekunden Dein Programm "nichts" zu tun hat.
Soll heißen, Du möchtest zB einen Grafik-FX (Scroller) alle 30 msec
neu berechnen und anzeigen lassen, die Berechnung und Darstellung
kostet jedoch nur 5 msec ( das ist natürlich Rechnerabhängig

), dann
könntest Du einen Delay von 25 msec verwenden.
Verfasst: 15.09.2004 18:50
von sbehrens
Thanks for the information!
@Sunny
Hmm, könnte man diesen künstlichen Delay() nicht mit SetFrameRate(x) erstellen? Aber das geht nur bei einem Screen... Warum testest (

cooles Wort) du deine Programme mit einem Delay() um einen langsamen Rechner zu simulieren? Möchtest du damit deine Programme möglichst effizient machen?
@Lars
Dann änder ich mein Standarddelay für Fenster auf 10
mfG
Basti
Verfasst: 15.09.2004 19:31
von Ynnus
@Sunny
Hmm, könnte man diesen künstlichen Delay() nicht mit SetFrameRate(x) erstellen? Aber das geht nur bei einem Screen... Warum testest ( Laughing cooles Wort) du deine Programme mit einem Delay() um einen langsamen Rechner zu simulieren? Möchtest du damit deine Programme möglichst effizient machen?
Nein, mit SetFrameRate(x) kann man doch nicht so tief wie 25, 15 oder 10 gehen, oder? Weil ich vor allem teste, wie mein Spiel mit wenigen FPS läuft. Es macht zwar kaum Sinn, es bei solch niederen Werten zu spielen, aber man muss ja mit allem rechnen.
Dummerweise sind auch zu viele FPS bei mir tödlich.
Ab 400 FPS (hab ich zeitweise) sind die Zeitgesteuerten Pixelbewegungen zu klein, sodass sich meine Figur nicht mehr bewegt.^^ Daher muss ich das sowieso mit VSync auf 60 FPS halten. Und um weiter runter zu drosseln, nehme ich dann am Ende der Schleife ein Delay(50) meinetwegen. Das ist aber schon recht extrem, danach hab ich nur noch 15 FPS oder so, von ehemals 400...
Verfasst: 15.09.2004 20:29
von sbehrens
400 Frames?!? OMG, sowas würde mein PC nicht schaffen, dazu ist er viel zu schlecht!
Sunny hat geschrieben:Nein, mit SetFrameRate(x) kann man doch nicht so tief wie 25, 15 oder 10 gehen, oder?
Doch, also bei mir geht es auf jeden Fall, ich habe es mit 5, 10, 15 Frames getestet und es scheint zu funzen:
Code: Alles auswählen
If InitSprite() And InitKeyboard()
OpenScreen(1024,768,32,"SetRefreshRate(x) Test")
SetFrameRate(10); das funzt bei mir! auch 5,15 usw. (mehr habe ich nicht getestet)
i.b=0
Repeat
ClearScreen(0,0,0)
ExamineKeyboard()
StartDrawing(ScreenOutput())
Locate(500,400)
DrawText(Str(i))
StopDrawing()
i=i+1
FlipBuffers()
Delay(1) ; kann man auch auslassen
Until KeyboardPushed(#PB_Key_Escape)
Else
MessageRequester("Error","Init...()")
EndIf
Und wie siehts bei dir aus?
mfG
Basti
Verfasst: 16.09.2004 00:41
von THEEX
@Sunny
Die richtige Methode ist das aber auch nicht gerade. Dann laß doch viel lieber Berechnen, wie weit Deine Figur/Animation in einer bestimmen Zeit sein soll und laß solange die gleiche Position/das gleiche Bild darstellen, bis genug Zeit vergangen ist.
Wenn ich mich richtig erinnere, hat Danilo in seinen PureTools sowas integriert, damit wird es dann sogar automatisch richtig berechnet, ohne das Du es selbst tun müßtest.
Verfasst: 16.09.2004 01:17
von Ynnus
Animieren tue ich meine Figuren ja auch Zeitbasiert. Also, direkt vorgegeben, z.B. 200 ms dauert ein Frame, wenn also die 200 ms verstrichen sind, wird ein Frame hoch geschaltet. Aber bei der Bewegung lass ich eben automatisch die FPS die Geschwindigkeit korrigieren, dass ich durch kleinere FPS einen größeren Schritt mache, und bei vielen FPS einen kleineren. Somit legt man in der gleichen Zeit die gleiche Strecke zurück.
Das Problem daran ist eben nur, dass bei ~400 FPS so langsam der Schritt pro Frame kleiner als ein Pixel beträgt und der Spieler sich erst ab ~350 wieder bewegt.
Dagegen meintest du dann wohl, wenn ich das recht verstehe, lieber eine gewisse Zeit verstreichen lassen, und dann die dazugehörige Strecke ablaufen.
Das wäre natürlich auch eine Lösung, derzeit mach ich es aber noch mit der anderen. Das jetzt umzustellen ist recht viel Arbeit. Und wenn die FPS nicht über ~360 kommen (werden sie später sowieso nicht mehr, wegen viel Rechnungen, mehr Sprites und außerdem ist VSync an, was die Frames auf maximal 100 drosselt).
Wenn es mal massive Probleme geben sollte, denk ich hier dran und versuch das mal umzustellen.
Dabei fällt mir nun ein Problem auf, welches man mit deiner Version hätte. Was ist nun, wenn man festlegt, die Figur bewegt sich um 1 Pixel alle 2 ms. Ist zwar recht schnell, in der Sekunde 500 Pixel, aber mal als Beispiel.
Wenn nun der Code so langsam durchläuft, dass er nie genau die 2 ms perfekt abpasst, sondern mal 1,8, beim nächsten Durchlauf ist es aber schon 2,4, dann ist das recht unregelmäßig. Eventuell wird er dann nächstes Mal korrekt bei 2,0 geschaltet, aber ist dennoch 0,4 ms versetzt zum letzten.
Oder aber der Rechner ist so langsam, dass er nur einige FPS schafft, und nur alle 4 ms die Schleife wiederholt. Das bedeutet ja dann, die Zeit von 2 ms ist erreich, also laufen wir die Strecke ab. Nun haben wir dann aber nur die Hälfte der Strecke, weil die Zeit ja schon 2fach abgelaufen ist...
Ok, dann könnte man nun den Fakor errechnen, um wie viel die Zeit überstrichen wurde, und so oft dann die Strecke abgehen. Im Beispiel also 2 mal, anstelle von 1 mal.
Aber durch die Verwendung von Floats (zwangsweise hier) trenten dann genauso ungereihmtheiten auf, wie als wenn ich die FPS mit dem Speed multipliziere, also meine derzeitige Methode.
Verfasst: 16.09.2004 02:56
von THEEX
Mir ist bewußt, daß die Zeitabstände zwischen den Frames unregelmäßig sein können, dafür muß natürlich auch ein Ausgleich geschaffen werden. Das ist wohl ein kleineres Problem.
Gehn wir jetzt von einem langsamen Rechner aus, bei dem kommt es vor, das ab und an zu wenig Strecke zurück gelegt würde, da er einfach zu langsam berechnet. Wo ist das Problem? Auch da kann ein Ausgleich geschaffen werden. Soll er nach 0.2 Sekunden einen Pixel zurücklegen, dann legt er, wenn schon 0.4 s verstrichen sind, eben 2 Pixel zurück (ich glaub das nennt man bei so manchem Game lagg).
Vielmehr seh ich es als Problem an, wenn Du deinen Rechner zwischen den Frames 0.2 s pausieren läßt (oder sagen wir mal, weil noch Rechenzeit dazwischen liegt, 0.1 s). In der Zeit kann nichts berechnet werden. Nun haste wieder einen langsamen Rechner und schlägst nach jeder Berechnung 0.2 (0.1) s Wartezeit drauf. Ja dann ist die Figur doch auf einmal zu langsam bzw. hätte der langsame Rechner es vielleicht in 0.2 s sogar berechnet. In einem Netzwerkgame hätte das verheerende folgen, man rennt langsamer als die anderen. Als Ausgleich könnest da natürlich größere Schritte machen lassen, aber durch Delay entsteht ein unnötiger Abstand.
Ich selbst würde in ein Programm nur Delays einbauen, um die CPU weniger zu belasten, aber nie, weil mein Rechner irgendetwas schneller berechnen kann, als er soll.
Qualitativ ist es einfach besser, wenn Du mit 200 FPS (obwohl das Auge so viel gar nicht wahrnehmen kann) zocken kannst, wenn auch nur 100 oder weniger benötigt werden.
Natürlich würde ich eine Figur immer die kleinstmögliche Strecke vorrücken lassen (das ist wohl ein Pixel), sobald genügend Zeit für die passende Entfernung vergangen ist.