Frameunabhängig programmieren
Übersicht BlitzBasic FAQ und Tutorials
IonPainterBetreff: Frameunabhängig programmieren |
Do, Mai 06, 2004 14:34 Antworten mit Zitat |
|
---|---|---|
Frameunabhängig programmieren
============================= ein Tutorial von IonPainter 1) Warum Frameunabhängig programmieren? ======================================= Wer Frameunabhängig programmiert, stellt sicher das auf jedem Computer, und sei er auch noch so langsam, sein Spiel mit immer gleichbleibender Geschwindigkeit läuft. Das ist besonders bei Multiplayerspielen wichtig die syncron laufen müssen. 2) Wie programmiere ich Frameunabhängig? ======================================== Es gibt viele Moglichkeiten, von abenteuerlichen FPS kalkulationen mit denen dann dividiert wird bis hin zu RenderWorld Parametern, u.s.w. Das ist eigentlich alles zu kompliziert, es geht auch viel einfacher: Man misst die Zeit die ein Schleifendurchlauf braucht und multipliziert sämtliche Bewegungsabläufe mit diesem Wert. Beispiel: Code: [AUSKLAPPEN] Graphics 640, 480 SetBuffer Backbuffer() While Not Keyhit(1) StartZeit = Millisecs() Cls ;Bewegen des Quadrats Position = Position + (1 * SchleifenZeit) ;Wenn Quadrat ganz Rechts dann setze Quadrat nach ganz links if Position > (640 - 16) then Position = 0 ;Zeichnen des Quadrates Rect Position, (240 - 8), 16, 16 Flip 0 ;60FPS Begrenzung ausschalten SchleifenZeit = Millisecs() - Startzeit Wend Das Rechteck bewegt sich relativ schnell und flüssig von Links nach Rechts. Um jetzt zu testen ob es wirklich Frameunabhängig läuft, verlangsamen wir die Ausführung. Code: [AUSKLAPPEN] Graphics 640, 480 SetBuffer Backbuffer() While Not Keyhit(1) StartZeit = Millisecs() Cls ;Bewegen des Quadrats Position = Position + (1 * SchleifenZeit) ;Wenn Quadrat ganz Rechts dann setze Quadrat nach ganz links if Position > (640 - 16) then Position = 0 ;Zeichnen des Quadrates Rect Position, (240 - 8), 16, 16 Delay Rand(25) Flip 0 ;60FPS Begrenzung ausschalten SchleifenZeit = Millisecs() - Startzeit Wend Hier werden zufällig kleine Pausen bis 25 Millisekunden in die Hauptschleife eingefügt. Trotzdem bewegt sich das Quadrat zwar ruckelnd, aber gleich schnell! Ganz schlaue (und faule) schreiben sich noch eine Funktion: Code: [AUSKLAPPEN] Global SchleifenZeit Graphics 640, 480 SetBuffer Backbuffer() While Not Keyhit(1) StartZeit = Millisecs() Cls ;Bewegen des Quadrats Position = Position + SZ#(1) ;Wenn Quadrat ganz Rechts dann setze Quadrat nach ganz links if Position > (640 - 16) then Position = 0 ;Zeichnen des Quadrates Rect Position, (240 - 8), 16, 16 Delay Rand(25) Flip 0 ;60FPS Begrenzung ausschalten SchleifenZeit = Millisecs() - Startzeit Wend Function SZ#(Bewegung) Wert# = Bewegung * SchleifenZeit Return Wert# End Function Nun braucht man nur noch SZ#(1) statt 1 * SchleifenZeit zu Tippen. Ausserdem bleibt der Code übersichtlicher. Hoffe mal das nun mehr BB-Programmierer das eigentlich so einfache frameunabhängige Programmieren praktizieren. Anregungen, Kritik, u.s.w. bitte hier Posten. Credit Me, IonPainter ========== |
||
Keimax |
Do, Sep 09, 2004 10:31 Antworten mit Zitat |
|
---|---|---|
IonPainter zeig mir mal wie ich eine flüssige Bewegung von Links nach Rechts hinbekomme.
Mit Flip 0 geht das nicht. Also bei mir auf jedenfall. Vielleicht liegts ja an meinem Monitor Erst wenn ich Flip auf 1 stelle siehts halbwegs vernünftig aus. cu |
||
XP3000, FX6600, 1024DDR, BB2d @ W2k,
- > Diesen Text bitte nicht beachten <- |
Tobchen |
Do, Sep 09, 2004 18:19 Antworten mit Zitat |
|
---|---|---|
So große Sprünge können einem die Kollision richtig versauen. Kann man das anders machen? Ich hatte immerCode: [AUSKLAPPEN] If TolleZeit + 25 < MilliSecs() Then ... Und diese Methode kann man auch ziemlich vergessen, wenn die FPS nicht viel sind.
|
||
Tobchen - die Welt von Tobi!
|
Freeman |
Do, Sep 09, 2004 22:08 Antworten mit Zitat |
|
---|---|---|
warum nutzt man hier nich die Timer funktion ? also createTimer und dann waittimer? damit kann man doch die fps rate auf nem bestimmten niveau halten, zumindest so das es nicht mehr überschritten wird...und ma ganz ehrlich, würdest du ne delay(time) funktion in deine schleife reinbaun? ich glaub wohl nich....
FrEeMaN |
||
walskiEhemaliger Admin |
Do, Sep 09, 2004 22:44 Antworten mit Zitat |
|
---|---|---|
Bei der frameabhängigen Programmierung geht es ja darum, hohe Rechnergeschwindigkeiten zur genaueren, flüssigeren Berechnung der Szenen zu nutzen, ohne dass es schneller abläuft als auf nem langsamen Recher.
Ein Begrenzen der Framerate auf beispielsweise 100 oder meinetwegen auch nur 40 ist schön und gut, aber warum soll der 3GHZ, Radeon 9800 Pro XTR GT SuperDuper [HierBeliebigesWichtigklingendesSuffixEinsetzen] Besitzer nicht auch seine Hardware nutzen können, indem er halt 900 Frames pro Sekunde rendert und alles schöööööön flüssig von der Hand geht? Oder andresrum, was machst du mit Usern die wirklich an der "40-FPS"-Grenze kratzen und bei denen sich gerade im Hintergrund ICQ zu Wort meldet... läuft das Spiel dann auf einmal langsamer... Im Netzwerk wäre dass dann doof Das nur zur Daseinsberechtigung des Ganzen. walski |
||
buh! |
Bura.Tino |
Di, Aug 30, 2005 12:52 Antworten mit Zitat |
|
---|---|---|
Die Sache ist doch die, daß das menschliche Augen 24 Frames pro Sekunde braucht um es nicht mehr als einzelne Bilder, sondern als Animation wahrzunehmen.
Deswegen kann man ein Spiel doch locker auf 30 FPS reduzieren. Auch wenn der Rechner 900 FPS bringen würde, so macht es doch gar keinen Sinn ! Für das menschliche Auge macht es nicht den geringsten Unterschied, ob das nun 30 oder 900 FPS sind. Fazit: Flüssig ist Flüssig. Alles andere ist egal. |
||
MegaTefyt |
Di, Aug 30, 2005 13:18 Antworten mit Zitat |
|
---|---|---|
Das ist definitiv falsch. Selbst wenn man (evt.!) keinen Unterschied sieht ist meist das Spielgefühl ein anderes, man spürt FPS-Unterschiede. Daher ist von einer 30 (oder weniger) FPS-Begrenzung abzuraten.
Im übrigen ist es sinnvoll sich eine Zusatzvariable für die MilliSecs() anzulegen, z.B. PAUSETIME%. Sprich überall wo MilliSecs() benutzt wird macht man ein MilliSecs() - PAUSETIME draus. Warum? Ganz einfach, die meisten wollen sicher eine Pause- (oder Menu-)Funktion in ihrem Spiel haben. Dabei läuft natürlich MilliSecs() weiter, obwohl das eigentliche Spiel gar nicht läuft. Das hat meistens ungewollte Folgen. Bei jeder Pause misst man die Zeit, wie lange das Spiel pausiert war, und addiert diesen Wert zur PAUSETIME dazu. Damit läuft das Spiel trotz Pausierung normal weiter wie es sollte. |
||
Xaron |
Di, Aug 30, 2005 14:08 Antworten mit Zitat |
|
---|---|---|
MegaTefyt hat Folgendes geschrieben: Das ist definitiv falsch. Selbst wenn man (evt.!) keinen Unterschied sieht ist meist das Spielgefühl ein anderes, man spürt FPS-Unterschiede.
Das liegt dann aber eher an der schlechten Programmierung. Sehen tut man den Unterschied wirklich nicht, "fühlen" auch nicht, wenn es ordentlich gemacht wurde - wie auch? Gruß - Xaron |
||
Cerberus X - Monkey X Reloaded! |
MegaTefyt |
Di, Aug 30, 2005 14:18 Antworten mit Zitat |
|
---|---|---|
Dann sind also alle Shooter schlecht programmiert, ja? Weil die sind das beste Beispiel dafür. Sie spielen sich allesamt besser mit 100+ FPS als nur mit 30 FPS, obwohl es laut euch ja keine Unterschiede geben dürfte. | ||
Bura.Tino |
Di, Aug 30, 2005 14:19 Antworten mit Zitat |
|
---|---|---|
Ja das wüsste ich auch zu gerne. Ich denke, das es nicht den geringsten Unterschied macht. Sehen tut man den Unterschied mit Sicherheit nicht, und fühlen denke ich auch nicht. Also ich bleibe dabei, das es keinen Unterschied gibt !
/edit: Wieso spielen die sich besser ??? |
||
D2006Administrator |
Di, Aug 30, 2005 15:58 Antworten mit Zitat |
|
---|---|---|
Beispiel:
Angenommen ein Objekt (Quadrat ... 5x5px) bewegt sich im Spiel auf eine 5px Mauer zu. Das ganze mit einer Geschwindigkeit von 200 Pixel pro Sekunde. Das bedeutet, das pro Schleifendurchgang das Objekt bei ... ... 30 FPS ganze 6 Pixel und 2/3 Pixel (was gerundet 7 Pixel macht) verschoben werden muss und bei ... ... 100 FPS das Objekt nur 2 Pixel verschoben werden muss. Sofort fällt auf, dass bei 30 FPS derart große Sprünge gemacht werden, dass die gute Mauer einfach übersprungen wird, obwohl das auf keinen Fall passieren darf. Ist sie erstmal übersprungen, lässt sich eine Kollision kaum noch feststellen. Bei 100 FPS allerdings macht das Objekt kleine Schritte und muss zwangsläufig irgendwann die Mauer berühren, wodurch wir eine Kollision ermitteln können. Man bemerkt: Je mehr FPS man hat, desto besser und genauer sind Berechnungen wie die der Kollision. Übrigens hier mal ein feiner Beispielcode: Code: [AUSKLAPPEN] Graphics 640,480,32
SetBuffer BackBuffer() fps# = 30 While Not KeyHit(1) start = MilliSecs() Cls fps# = fps# + (KeyDown(205)-KeyDown(203))/5.0 Text 10,10,fps# Rect x#,50,10,10,1 x#=x# + zeit/2.0 If x#>640 Then x#=-20 f=0 Repeat f=f+1 Until MilliSecs()>timer + (1/fps#)*1000 timer=MilliSecs() Text 10,80,f zeit = MilliSecs() - start Flip 0 Wend End Mit Links/Rechts könnt ihr die FPS (obere Zahl) manipulieren. Nun sagt mir einer mal, dass das bei 30 FPS genauso aussieht wie zB bei 90. Die untere Zahl gibt übrigens an, wie viel Rechenpower man verschenkt. Wenn da eine 1 steht und sich das Quadrat langsam bewegt, sind die FPS zu hoch eingestellt. MfG D2006 |
||
Xaron |
Di, Aug 30, 2005 16:11 Antworten mit Zitat |
|
---|---|---|
Da muss ich widersprechen. Tokamak z.B. verwendet nicht ohne Grund keine fps-basierte sondern eine frame-basierte Technik, um die Physik zu berechnen. Es kann sonst nämlich bei hohen FPS-Werten aufgrund zu kleiner Zahlen sehr schnell zu sehr großen Problemen kommen.
Dazu empfehle ich mal, folgenden Artikel zu lesen: http://www.gaffer.org/articles/Timestep.html Bei Standard-0815-"Physik"-Experimenten ist das natürlich anders. Gruß - Xaron |
||
Cerberus X - Monkey X Reloaded! |
Bura.Tino |
Di, Aug 30, 2005 16:38 Antworten mit Zitat |
|
---|---|---|
Also irgendwas stimmt an Deinem Code nicht. Bei 30 FPS läuft er flüssig und bei 900 springt das Quadrat.
Es ist dann keine wirkliche Animation mehr zu erkennen ! |
||
D2006Administrator |
Di, Aug 30, 2005 17:12 Antworten mit Zitat |
|
---|---|---|
Xaron hat Folgendes geschrieben: Da muss ich widersprechen. Tokamak z.B. verwendet nicht ohne Grund keine fps-basierte sondern eine frame-basierte Technik, um die Physik zu berechnen. Es kann sonst nämlich bei hohen FPS-Werten aufgrund zu kleiner Zahlen sehr schnell zu sehr großen Problemen kommen.
Dazu empfehle ich mal, folgenden Artikel zu lesen: http://www.gaffer.org/articles/Timestep.html Bei Standard-0815-"Physik"-Experimenten ist das natürlich anders. Ähem. Sorry. Da bist du wohl ein klein wenig am Thema vorbei geschossen. Wir reden doch hier über diese eine Methode des frameunabhängigen Programmierens. Du beschreibst ein anderes, vielleicht sogar besseres, für das Programmieren von Hobbyprojekten vielleicht nicht notwendiges Verfahren. Bei diesem Verfahren hier geht es aber NUR darum, die Physikberechnungen an die Framezahl anzupassen. Um zum Thema zurück zu kommen: Siehst du nun, dass es bei 90 FPS besser aussieht als bei 30 FPS oder stimmt etwas mit deinen (vielleicht auch meinen) Augen nicht? @Bura.Tino: Irgendwas machst du falsch. Um 900 FPS auszuprobieren, musst du auf jedenfall Flip 0 einsetzen. Ich mage zumindest bezweifeln, dass dein Monitor eine Bildwiederholfreqeunz von 900 Hz hat. Wie gesagt, ist die untere Zahl "1", so sind die FPS zu hoch gewählt. (Etwa bei 2000 FPS ist das sowieso der Fall, weil dann die Millisekundenschritte kleiner 1 wären, was natürlich nicht geht, da MilliSecs() ja eine Integerfunktion ist) MfG D2006 |
||
Bura.Tino |
Di, Aug 30, 2005 18:45 Antworten mit Zitat |
|
---|---|---|
Flip ist auf 0 gesetzt !
Ich habe den Code so übernommen wie Du ihn gepostet hast. Und trotzdem kann da was nicht stimmen. Je höher ich in den FPS gehe, desto mehr ruckelt es. Die untere Zahl wie Du sie nennst ist keineswegs "1" ! Sie bewegt sich im 5-stelligen Bereich ! Oder hab ich da was falsch verstanden ? |
||
SpionAtom |
Do, Sep 15, 2005 0:10 Antworten mit Zitat |
|
---|---|---|
Bura.Tino hat Folgendes geschrieben: Die Sache ist doch die, daß das menschliche Augen 24 Frames pro Sekunde braucht um es nicht mehr als einzelne Bilder, sondern als Animation wahrzunehmen.
^^ Auch ich möchte hier meinen Senf dazugeben. Denn auch ich halte diese Aussage für falsch. Richtig ist, dass bei 24-25 Bildern pro Sekunde keine Einzelbilder mehr zu erkennen sind. Aber dennoch erfährt man mit zunehmenden FPS eine angenehmere Animation. Alles wirkt flüssiger und weicher, weil weniger Bilder ausfallen. (Im Idealfall, was nie zu erreichen sein wird, fehlen theoretisch gar keine Animationsschritte; und man will programmiertechnisch ja wenigstens so weit wie möglich die Theorie einholen ) |
||
d-bug |
Do, Sep 15, 2005 7:28 Antworten mit Zitat |
|
---|---|---|
@Bura.Tino
Bisschen Spät jetzt, aber dieser Effekt ist doch eigentlich schon Standard. Ich nehme einfach mal an, daß du deinen Test im Fenstermodus gemacht hast. Dieser Effekt nennt sich tearing. Ein wenig Lektüre zum tearing findest du hier... |
||
Silvio |
Fr, Feb 03, 2012 22:42 Antworten mit Zitat |
|
---|---|---|
Ich hab das angewandt, aber jetzt bewegen sich alle Figuren sehr sehr schnell. Sie werden ja jeden Schleifendurchlauf mindestens 1 Pixel bewegt. Wie kann ich jetzt langsame Bewegungen herstellen? Ich kann ja nicht die SchleifenZeit mit was kleinerem als 1 multiplizieren, da man nicht um 0.1 Pixel oder so bewegen kann. | ||
ozzi789 |
Fr, Feb 03, 2012 23:12 Antworten mit Zitat |
|
---|---|---|
Du hast einen Thread aus 2005 ausgegraben, das bestimmt ein Rekord!
Wird hier nicht so gerne gesehn.. Doch du verwendest einen Float und verwendest eine zweite Variable für Drawimage die du mit Ceil und Int bearbeitest. Oder du erhöhst es jeden 2ten Schleifendurchgang was weis ich.. |
||
0x2B || ! 0x2B
C# | C++13 | Java 7 | PHP 5 |
Eingeproggt |
Fr, Feb 03, 2012 23:15 Antworten mit Zitat |
|
---|---|---|
Ohne das Tut angeschaut zu haben würde ich meinen das mit 0.1 Pixel geht sehr wohl, siehe dazu den Datentyp Float, verwendbar wenn man ein # hinter eine Variable schreibt:
BlitzBasic: [AUSKLAPPEN] speed#=0.1
Dann wird intern mit 0.1 gerechnet... dass sich die Figur dann aber nur recht "stückweise" über den Bildschirm bewegt da sie auf gerundete ganze Pixelwerte gezeichnet wird ist halt ein anderes Problem für das ich aktuell keine Lösung hab... Aber bis jetzt sah so ein Vorgehen durchaus brauchbar aus. mfG, Christoph. |
||
Gewinner des BCC 18, 33 und 65 sowie MiniBCC 9 |
Übersicht BlitzBasic FAQ und Tutorials
Powered by phpBB © 2001 - 2006, phpBB Group