Registriert: Di Okt 13, 2009 17:25 Beiträge: 365
Programmiersprache: C++
Okay, ich schätze ich bin überstimmt. Das mit dem Netzwerk ist ein echtes Argument, das hatte ich noch nicht bedacht.
@Ziz: Wenn auf der Strecke zwischen den Frames ein Hindernis liegt, kann man doch an dieser Stelle die Auswirkungen auf die Bewegung der beteiligten Objekte berechnen. Von dort kann man einen neuen (Kugel- / was-auch-immer-)Strahl in die neue Richtung mit der neuen Geschwindigkeit losschicken, den man erneut auf Kollision prüft usw. usf. Sicherlich wird es sehr schwierig bis unmöglich, zu simulieren wenn fünf Objekte zur selben Zeit aufeinander treffen. Das passiert in der Praxis imho aber auch selten.
Zitat:
Was ist mit Objekten mit einer beschleunigten Bewegung oder gar einer nicht vorhersehbaren Beschleunigung?
Zwei Möglichkeiten: Entweder man baut die Beschleunigungsfunktion in die Kollisionserkennung mit ein (ist natürlich aufwändiger) oder aber man verliert an Präzision. Unter "einer nicht vorhersehbaren Beschleunigung" kann ich mir gerade nicht besonders viel vorstellen. Kannst du bitte mal ein Beispiel nennen? Eigentlich haben doch alle Beschleunigungen ein Ursache?
Ich gebe zu, dass es für den Programmierer einfacher ist, einfach eine normale Kollisionserkennung ohne Bewegung mehrfach pro Frame aufzurufen. Aber dass das schneller ist, glaube ich nicht.
Gruß mrtrain
Zuletzt geändert von mrtrain am Mi Aug 31, 2011 19:19, insgesamt 1-mal geändert.
Registriert: Di Mai 18, 2004 16:45 Beiträge: 2623 Wohnort: Berlin
Programmiersprache: Go, C/C++
Eine Vorhersage, ob ein Physik Objekt zwischen letzten und jetzigen Schritt geschnitten hat, kann nur durch sehr sehr sehr komplexes Vorgehen fest gestellt werden. Hierzu, muss man erstmal raus bekommen, ob es möglich ist sich zu schneiden. Dies bedeutet aber man müsste quasi letzten und aktuelles Intervall nehmen und unendlich viele male unterteilen. Jedes Intervall müsste nun getestet werden, das kann man nicht machen und man greift zu tricks und ungenauen methoden.
Also das testen mit einem ray, volume oder ähnlichem wird immer Probleme machen, da es erstens mehrere Kräfte gibt und das Objekt sich in 4 Dimmensionen verändert. X,Y,Z kann man noch recht gut im Zaun halten aber Zeit ist das Problem des Intervalles. Sagen wir, wir legen eine festes Intervall fest und wir haben im letzten Schritt zu wenig zeit gehabt und sind über das Intervall rüber gerutscht, dann kann man nun das letzte Interval und das eigentlich geplante Intervall nehmen, dann berechnet man das geplante Intervall, setzt alle Objekte und Kräfte und spult die Zeit auf das Delta wo wir drüber sind. Die Physik arbeitet also im Rahmen des Vorgaben immer korrekt. Das Problem ist, wenn die Kiste einbricht, dann nicht nur einmal sondern einige Intervalle und das ganze summiert sich dann ganz nett auf und sieht wie ein Gummiband in den nicht so stark belastetet bereich nach. Also zu wenig Power ist immer ein Problem aber kann mit festen Hz sehr stabil laufen. Hierzu findet man dann auch in der Regel Informationen, wie z.B. bei Bullet, wo man nicht mehr als 5m/s also 18km/h bei einer Objektgröße von 1Unit/Meter überschreitet sollte, da sonnst das default 60Hz Intervall nicht mehr genau genug ist und Objekte durch Wände rutschen ohne, dass es realisiert wird. Eine höhere Hz Zahl würde diesen Wert natürlich ändern.
_________________ "Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren" Benjamin Franklin
Registriert: Di Mär 21, 2006 20:03 Beiträge: 21
Programmiersprache: Delphi, C++
Lord Horazont hat geschrieben:
Bei einigen Spielen würde ein Komplettabgleich einiges an Bandbreite beanspruchen
Stimmt. Das hatte ich nicht bedacht. Die Position wo sich ein Spieler gerade aufhält, wird aber doch abgeglichen. Oder? Z.B. weil eine Änderung der Bewegung nicht korrekt oder gar überhaupt nicht beim Server ankam. Der Server sendet dem Spieler dann doch schon, wo er sich - laut Server - befindet. Daher stammen doch Laggs in Form von kleinen "Warps", oder?
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
@aniheX: Teilweise. Das hängt vom Spiel ab. bei RPGs und Shootern wahrscheinlich schon, bei einem komplexen Real-Time-Strategy-Game wohl eher nicht, weil du da entweder alle oder keine Objekte syncen musst. Gerade für letztere ist dann eine Physik in festen Zeitintervallen wichtig.
mrtrain hat geschrieben:
Möglichkeiten: Entweder man baut die Beschleunigungsfunktion in die Kollisionserkennung mit ein (ist natürlich aufwändiger) oder aber man verliert an Präzision. Unter "einer nicht vorhersehbaren Beschleunigung" kann ich mir gerade nicht besonders viel vorstellen. Kannst du bitte mal ein Beispiel nennen? Eigentlich haben doch alle Beschleunigungen ein Ursache?
Naja, stell dir vor, du hast z.B. ein explosives Projektil, was kurz davor ist, auf dem Boden aufzuschlagen, an Position X=2. Zusätzlich zwei Fahrzeuge, eins an Position X=0 und eines an Position X=3, Y=10. Fahrzeug eins bewegt sich in positive X richtung, Fahrzeug zwei in negative Y Richtung. Eine spontane, nicht vorhersehbare (denn du musst diese Werte schon vor der Kollisionsabfrage kennen) wäre jetzt, wenn das Projektil einschlägt und die Druckwelle Fahrzeug 1 wegreißt, sodass keine Kollision zwischen Fahrzeug 1 und Fahrzeug 2 stattfindet. Das Projektil kollidiert auch nicht direkt mit Fahrzeug 1, sondern mit dem Boden, sodass du nicht mal darüber einen direkten Zusammenhang ziehen kannst.
greetings
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Registriert: Di Okt 13, 2009 17:25 Beiträge: 365
Programmiersprache: C++
Ihr habt mich überzeugt, ich werde in Zukunft auf Physik mit fester Frequenz setzen. Thx @all für die Aufklärung, auch wenn - sorry aniheX - das eigentlich gar nicht mein Thread ist.
Alles Gute
Zuletzt geändert von mrtrain am Mi Aug 31, 2011 19:18, insgesamt 1-mal geändert.
Registriert: Di Mär 21, 2006 20:03 Beiträge: 21
Programmiersprache: Delphi, C++
Warum denn sorry? o,o
Ich hatte diesen Thread aufgemacht weil mich fragte, warum viele vom "klassischen" Time-Based Movement reden, obwohl diese Lösung für mich irgendwie viel schlüssiger und vor allem einfacher umzusetzen schien. Daher fragte ich auch nach eurer Meinung. Denn das sie im 2D Bereich gut funktioniert ist für mich bewiesene Sache. Aber wie das bei 3D Anwendungen/Spielen ist, war mir nicht ganz klar. Und wo könnte ich das besser herausfinden als in einem Forum von 3D Programmierern die auch noch deutsch verstehen? Dass dieses Verfahren bei Phsyik eigentlich üblich ist, war mir nicht bewusst. Ich habe das "klassische" Time-Based Movement übersprungen und bin von Frame-Based direkt auf dieses Time-Based umgestiegen. Sicher, ich hatte vergessen in meinem ersten Post vergessen zu erwähnen, dass man die Kollision (bei unbewegten Objecten) zurückverfolgen kann, allerdings schien mir das, wie gesagt zu umständlich und zu ungenau.
Es war zwar weder als Tutorial noch Belehrung gedacht, aber ... Wenn es dir geholfen hat, eine bessere Methode zu finden und diese einzusetzen, freue ich mich. Wir lernen doch alle noch dazu. Oder? Ich hab ja selbst noch einiges dazugelernt.
Registriert: Di Mär 21, 2006 20:03 Beiträge: 21
Programmiersprache: Delphi, C++
Entschuldigt bitte diesen Doppelpost.
In einem englischen Forum hab ich versucht, dies als ein kleines Tutorial zu erklären, als alternative zum Frame-Based Movement. Einige User zweifeln sehr stark an der Effektivität und meinen ich habe Fehler in meinen Quelltexten. Da einige Argumente - für mein laienhaftes Wissen - durchaus schlüssig sind, frage ich mich was ihr dazu meint.
Den Thread findet ihr im Moosaders Forum. Etwas, dass ihr da aber nicht findet, da es in meinem MSN steht ist, ist folgender Gesprächsverlauf (nur relevante Dinge):
LD hat geschrieben:
if your cpu loop is set to 60 fps but the computer can only render 30fps then your cpu loop is set to 30fps becasue the computer cant render it any faster then that
ani hat geschrieben:
Want me to prove it? This PC is NOT able to render the game with 100 FPS Still it's updating the game every 10 ms (makes 100 Updates each second)
LD hat geschrieben:
i assume update() and render() access the same varibles? your engine isnt multi-threaded, its still single-threaded
ani hat geschrieben:
SDL creates a new thread when using timers Would a timer be in the same thread like everything else, I wonder why I can't use PollEvents() which is only usable in the main thread
LD hat geschrieben:
i dont think you realise whats happening yoru doing this
<Anmerkung: Wir gingen davon aus, dass Update() mit 60 Hz aufgerufen wird, die FPS aber bei genau 120 liegen>
the timer itself probably isnt <Anmerkung: Multithreded> but the update and render code is which means the varibles they interact with is in the same thread your corrupting your rendering this is why i said i'd code it my way on the thread but bang, suddenly if the computer is too slow to run the game at full fps, then the cpu frame rate drops
Registriert: Di Mai 18, 2004 16:45 Beiträge: 2623 Wohnort: Berlin
Programmiersprache: Go, C/C++
1.) falsch, da man zwischen Rendern, Physik, Sound und so weiter parallelisiert, alles was in Prinzip ne eigene IO hat. Daher kann sehr wohl Logik 60 mal laufen und nur 30mal gerendert werden. 2.)FPS != Hz, bei FPS ist die rede von Frames per second und damit sind Bilder pro sekunden gemeint, was nur auf das Rendern bezug nimmt und nicht auf andere Teile. Hz ist eine wesentlich bessere Einheit, da es Frequenz oder Vorgänge pro Sekunde bedeutet und wesentlich allgemeiner ist. 3.)falsch, zugriff aus mehreren threads auf eine gemeinsame variable führt nicht zu single threaded, hier gibt es z.B. atomic operations, welche seit man PS3, X-Box360 und mehrkern CPUs hat zum standard werden und die langsamen und zu single thread ausführung führenden Mutex,Semaphore, Critical Section und wie man sie noch so nennt ersetzen. 4.)Der Code ist ziemlicher murks. man trennt alle IO's in Threads auf und sie laufen nebeneinander(auf mehrere Kerne verteilt bzw. bei 1Kern systemen in time window's) und nicht nacheinander(ein einziger Kern) in einer Loop. Natürlich gibt es Verbindungen zwischen Threads, es macht z.B. wenig Sinn schon die Physik von Game zu berechnen, wenn die Texturen und zum Rendern, die Sounds/Musik für Audio ausgabe noch nicht geladen sind. Genauso warten einige Threads auf andere, wenn sie schon fertig sind, um nicht Ressourcen zu verschwenden. 5.)- 6.)Zu kurz nachgedacht, dafür hat man doublebuffering in multithreaded software. Also man legt mehrere Speicherbereiche an und macht sie zu einem RingBuffer, dann wird bei jeden physik update geswitched und wenn der renderer dran ist, kann er die Daten lesen und die physik kann schon im nächsten buffer schreiben, das verschieben des cursors auf dem RingBuffer muss allerdings geschehen, wenn der Renderer fertig ist mit dem lesen(sonnst könnte er Daten zeichnen wollen, die die Physik schon wieder überschreibt). Normal sind 2 Buffer, ein Front- und BackBuffer. Du kannst also abfragen, ob der Buffer geswapped wurde und den Frontbuffer auslesen und die darin enthaltenden Physikdaten in die renderpipeline schicken, vor dem Renderer.SwapBuffer machst du ein Physic,SwapBuffer, damit die Physik schon wärend des Renderprozesses die nächsten fertigen Physikdaten in den Frontbuffer schiebt. Das der Physic Frontbuffer nun befüllt wurde fragst du erneut ab und wartest solange bis dies der fall ist, dann wieder in die Renderpipeline schieben und so weiter.
_________________ "Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren" Benjamin Franklin
Registriert: Di Mai 18, 2004 16:45 Beiträge: 2623 Wohnort: Berlin
Programmiersprache: Go, C/C++
Die Variante von 6.) ist natürlich umständlich, wenn man auf ein Frame mehrere Logik/Physik und so weiter Durchläufe plant. Da ist es sinnvoller auf Anforderung ein voll durchlaufenden Stand zu kopieren und zu übergeben. Also sowas: -frage nach aktuellen Physik Puffer(blocking bis der Frontbuffer aktualisiert wurde) -führe Zeichenbefehle aus -Renderer.SwapBuffer(blocking weil man erst bei Beendigung des Zeichenvorgangs Back und Frontbuffer wechselt) Wenn eine Collision auftritt und diese ein Sound abspielen soll, dann könnte man z.B. auf messages setzen. Hierbei nutzt man ein MessageQueue im Soundsystem, welchem man bei Kollision dann ein entsprechendes PlaySoundXY übergibt. Sobald das SoundSystem bei der Message an kommt, wird sie diese Verarbeiten und aus dem Queue entfernen.
Man nennt diese beiden Arten von kommunikation Push- und Poll-Verfahren, welche ihre Vor- und Nachteile haben.
Ja es ist nicht ganz einfach ^^
_________________ "Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren" Benjamin Franklin
Registriert: Di Mär 21, 2006 20:03 Beiträge: 21
Programmiersprache: Delphi, C++
4.) Welchen Code meinst du konkret? Es ist mehr als nur ein Code Abschnitt ... 6a.) Kann ess ein, dass SDL den Buffer sperrt, sobald ich SDL_Flip() bzw. DL_Swap() aufrufe? Egal wieviele FPS ich habe - auch wenn es über 2.000 sind - hatte ich bisher nie eine Kollision zwischen Renderer / Ablauflogik. Das beide Threads jedoch zur selben Zeit aufgerufen werden sollte aber recht wahrscheinlich sein
Zudem halte ich es für problematisch, dass man die Events nicht in einem anderen Thread als den Hauptthread abfragen kann. Das schränkt meine Idee nämlich wieder ein wenig ein.
Zudem halte ich es für problematisch, dass man die Events nicht in einem anderen Thread als den Hauptthread abfragen kann. Das schränkt meine Idee nämlich wieder ein wenig ein.
Das senden geht mit doch PostThreadMessage. Zur not schickt man alle empfangenen Messages an die Threads weiter.
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Das klingt aber verdächtig nach WinAPI und ist mit SDL dann ein Schuss in den Fuß. Nein, für sowas würde sich wieder so eine selbstgebaute MessageQueue mit Push-Pull-Verhalten, wie tak sie beschreibt, eignen.
greetings
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Mitglieder in diesem Forum: 0 Mitglieder und 7 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.