Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Di Jul 15, 2025 20:47

Foren-Übersicht » Programmierung » Einsteiger-Fragen
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 27 Beiträge ]  Gehe zu Seite Vorherige  1, 2
Autor Nachricht
BeitragVerfasst: Mi Mai 12, 2010 12:58 
Offline
DGL Member

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. :o

@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.

Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Mai 12, 2010 13:39 
Offline
DGL Member
Benutzeravatar

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

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Mai 12, 2010 14:38 
Offline
DGL Member
Benutzeravatar

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?


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Mai 12, 2010 14:40 
Offline
DGL Member
Benutzeravatar

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 networkmy 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


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Mai 12, 2010 18:19 
Offline
DGL Member

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. :lol: 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.

Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Mai 12, 2010 20:09 
Offline
DGL Member
Benutzeravatar

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? :D
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 ... :roll:
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.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Fr Mai 14, 2010 16:05 
Offline
DGL Member
Benutzeravatar

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>
Code:
void Render() {
draw(player);
update();
draw(enemy1);
draw(enemy2);
update();
draw(enemy3)
}
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
Code:
UpdateTimer = SDL_AddTimer(10, SetDoUpdateToTrue, NULL);

//main loop while ( !QuitGame)
{
   if (DoUpdate)
   {
      Update();
   } Render();
}

void Render()
{
   draw(player);
   update();
   draw(enemy1);
   draw(enemy2);
   update();
   draw(enemy3);
}
that is what your doing, i'm certain of it

[...]
you havent checked if the update loop was updateing at the time
ani hat geschrieben:
I didn't?
Code:
Uint32 Update(Uint32 Intervall, void *Parameter)
{
   if ( UpdateIsActive )
   {
      return 10;
   }
   UpdateIsActive = true;

   // Update everything

   UpdateIsActive = false;
   return 10;
}
LD hat geschrieben:
if the update loop was updating when you were rendering
if it is then you have to wait till it has updated
or again your corrupting your render stack.
ani hat geschrieben:
You should reverse it then.
Code:
Uint32 Update(Uint32 Intervall, void *Parameter)
{
   if ( UpdateIsActive or IsRendering )
   {
      return 10;
   }
   UpdateIsActive = true;

   // Update everything

   UpdateIsActive = false;

   return 10;
}

Rendering is WAY slower than updating.
LD hat geschrieben:
its not that easy
where as its not always updating


Vielleicht hat ja jemand massive Langeweile und hat grad Lust mir ebenfalls an den Kopf zu werfen, was für einen Mist ich da gemacht habe. ^^"


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Fr Mai 14, 2010 19:12 
Offline
DGL Member
Benutzeravatar

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

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Fr Mai 14, 2010 19:28 
Offline
DGL Member
Benutzeravatar

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

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Sa Mai 15, 2010 00:03 
Offline
DGL Member
Benutzeravatar

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.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Sa Mai 15, 2010 11:06 
Offline
DGL Member
Benutzeravatar

Registriert: Do Okt 16, 2008 13:18
Beiträge: 252
aniheX hat geschrieben:
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.
Code:
const
MyMESSAGE=WM_APP+1;
...
implementation

Thread1:
PostThreadMessage(ThreadID,MYMESSAGE,0,0) ; // Nachricht schicken

Thread2:
If PeekMessage(Msg, 0, MYMESSAGE, MYMESSAGE, PM_REMOVE) then

_________________
You even trying ...

Website: http://rise-of-light.de/


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Sa Mai 15, 2010 12:00 
Offline
DGL Member
Benutzeravatar

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 networkmy 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


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 27 Beiträge ]  Gehe zu Seite Vorherige  1, 2
Foren-Übersicht » Programmierung » Einsteiger-Fragen


Wer ist online?

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.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.009s | 14 Queries | GZIP : On ]